summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Wenning <wenning@us.ibm.com>2012-07-17 15:02:16 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2012-07-30 19:10:30 -0500
commitd3067d6f6e86e7ff1b795d9e67c9f298e18dfbbd (patch)
treea0fd7dfe901d0b06762b20746760629262191956
parent0dbf0dfdd65a967045976979a33569db73fc0878 (diff)
downloadtalos-hostboot-d3067d6f6e86e7ff1b795d9e67c9f298e18dfbbd.tar.gz
talos-hostboot-d3067d6f6e86e7ff1b795d9e67c9f298e18dfbbd.zip
Implement proc_set_pore_bar HWP
Change-Id: I95562f9c3bb85e3b283020f62beaf65752281167 RTC: 42150 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/1393 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
-rw-r--r--src/include/usr/hwpf/istepreasoncodes.H3
-rw-r--r--src/include/usr/targeting/common/utilFilter.H8
-rw-r--r--src/include/usr/vmmconst.h5
-rw-r--r--src/usr/hwpf/hwp/build_winkle_images/build_winkle_images.C336
-rw-r--r--src/usr/hwpf/hwp/build_winkle_images/makefile12
-rw-r--r--src/usr/hwpf/hwp/build_winkle_images/pore_gen_cpureg/HvPlicModule.H24
-rw-r--r--src/usr/hwpf/hwp/build_winkle_images/pore_gen_cpureg/p8_pore_table_gen_api.H286
-rw-r--r--src/usr/hwpf/hwp/build_winkle_images/proc_pba_bar_config/proc_pba_bar_config.C254
-rw-r--r--src/usr/hwpf/hwp/build_winkle_images/proc_pba_bar_config/proc_pba_bar_config.H57
-rw-r--r--src/usr/hwpf/hwp/build_winkle_images/proc_pba_bar_config/proc_pba_bar_config_errors.xml56
-rw-r--r--src/usr/hwpf/hwp/build_winkle_images/proc_set_pore_bar/proc_pba_init.H209
-rw-r--r--src/usr/hwpf/hwp/build_winkle_images/proc_set_pore_bar/proc_pm.H74
-rw-r--r--src/usr/hwpf/hwp/build_winkle_images/proc_set_pore_bar/proc_set_pore_bar.C463
-rw-r--r--src/usr/hwpf/hwp/build_winkle_images/proc_set_pore_bar/proc_set_pore_bar.H123
-rw-r--r--src/usr/hwpf/hwp/build_winkle_images/proc_set_pore_bar/proc_set_pore_bar_errors.xml56
-rw-r--r--src/usr/hwpf/hwp/build_winkle_images/proc_set_pore_bar/sbe_xip_image.h1749
-rw-r--r--src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/p8_delta_scan_rw.h278
-rw-r--r--src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/p8_image_help.C452
-rw-r--r--src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/p8_pore_api_const.h20
-rw-r--r--src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/p8_pore_table_gen_api.H168
-rw-r--r--src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/proc_slw_build.C88
-rw-r--r--src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/proc_slw_build.H2
-rw-r--r--src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/proc_slw_build_errors.xml2
-rw-r--r--src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/sbe_xip_image.c265
-rw-r--r--src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/sbe_xip_image.h146
-rw-r--r--src/usr/hwpf/hwp/core_activate/core_activate.C169
-rw-r--r--src/usr/hwpf/makefile4
-rw-r--r--src/usr/pnor/pnordd.C14
-rw-r--r--src/usr/targeting/common/utilFilter.C56
-rw-r--r--src/usr/targeting/common/xmltohb/attribute_types.xml28
-rw-r--r--src/usr/targeting/common/xmltohb/target_types.xml4
31 files changed, 4794 insertions, 617 deletions
diff --git a/src/include/usr/hwpf/istepreasoncodes.H b/src/include/usr/hwpf/istepreasoncodes.H
index c186e1e87..084f633ae 100644
--- a/src/include/usr/hwpf/istepreasoncodes.H
+++ b/src/include/usr/hwpf/istepreasoncodes.H
@@ -51,6 +51,8 @@ enum istepModuleId
ISTEP_START_PAYLOAD_CALL_SHUTDOWN = 0x02,
ISTEP_START_PAYLOAD_NOTIFY_FSP = 0x03,
ISTEP_ACTIVATE_SLAVE_CORES = 0x04,
+ ISTEP_BUILD_WINKLE_IMAGES = 0x05,
+ ISTEP_CORE_ACTIVATE = 0x06,
};
/**
@@ -66,6 +68,7 @@ enum istepReasonCode
ISTEP_TARGET_NULL = ISTEP_COMP_ID | 0x02,
ISTEP_MBOX_MSG_NULL = ISTEP_COMP_ID | 0x03,
ISTEP_BAD_RC = ISTEP_COMP_ID | 0x04,
+ ISTEP_FAIL_MASTER_WINKLE_RC = ISTEP_COMP_ID | 0x05,
};
}; // end ISTEP
diff --git a/src/include/usr/targeting/common/utilFilter.H b/src/include/usr/targeting/common/utilFilter.H
index 9b58b2fdb..b33afa6f6 100644
--- a/src/include/usr/targeting/common/utilFilter.H
+++ b/src/include/usr/targeting/common/utilFilter.H
@@ -131,6 +131,14 @@ void getAllLogicalCards( TARGETING::TargetHandleList & o_vector,
TYPE i_cardType,
bool i_functional = true );
+
+/**
+ * @brief find master core in system
+ *
+ * @return master target core, NULL otherwise
+ */
+const TARGETING::Target * getMasterCore( );
+
}
#endif // __TARGETING_COMMON_UTIL_H
diff --git a/src/include/usr/vmmconst.h b/src/include/usr/vmmconst.h
index ee531ca86..9c569289d 100644
--- a/src/include/usr/vmmconst.h
+++ b/src/include/usr/vmmconst.h
@@ -89,9 +89,10 @@ enum BlockPriority
/** Page Size in bits per SLBE */
#define SLBE_b 12
-/** Hardwired pointer to output PORE image, temporary location */
+/** Hardwired pointer to output SLW image, temporary location */
+/** SLW image must be on 1M boundary */
/** MAX image size is 512 K */
-#define OUTPUT_PORE_IMG_ADDR 0x780000
+#define OUTPUT_PORE_IMG_ADDR 0x400000
#define MAX_OUTPUT_PORE_IMG_SIZE 512*1024
diff --git a/src/usr/hwpf/hwp/build_winkle_images/build_winkle_images.C b/src/usr/hwpf/hwp/build_winkle_images/build_winkle_images.C
index e2ad1fec6..afabde42a 100644
--- a/src/usr/hwpf/hwp/build_winkle_images/build_winkle_images.C
+++ b/src/usr/hwpf/hwp/build_winkle_images/build_winkle_images.C
@@ -34,6 +34,7 @@
/******************************************************************************/
#include <stdint.h>
+#include <sys/misc.h> // cpu_thread_count()
#include <vfs/vfs.H> // PORE image
#include <trace/interface.H>
@@ -59,7 +60,7 @@
// Uncomment these files as they become available:
#include "proc_slw_build/proc_slw_build.H"
-// #include "proc_set_pore_bar/proc_set_pore_bar.H"
+#include "proc_set_pore_bar/proc_set_pore_bar.H"
namespace BUILD_WINKLE_IMAGES
{
@@ -73,11 +74,9 @@ using namespace DeviceFW;
/**
* @def pointer to area for output PORE image
* @todo - make system call to allocate 512k - 1M of space to put output
- * image. Currently hardwired to 0x78000
- *
+ * image for the master chip.
+ * Currently hardwired to 0x400000
*/
-void * const g_pOutputPoreImg
- = reinterpret_cast<void * const >(OUTPUT_PORE_IMG_ADDR);
/**
* @brief Load PORE image and return a pointer to it, or NULL
@@ -94,9 +93,9 @@ void * const g_pOutputPoreImg
* HWP's are finished.
*
*/
-errlHndl_t loadPoreImage( TARGETING::Target *i_CpuTarget,
- const char *& o_rporeAddr,
- size_t & o_rporeSize )
+errlHndl_t loadPoreImage( const TARGETING::Target *i_CpuTarget,
+ const char *& o_rporeAddr,
+ size_t & o_rporeSize )
{
errlHndl_t l_errl = NULL;
const char * fileName = "procpore.dat";
@@ -152,6 +151,144 @@ errlHndl_t loadPoreImage( TARGETING::Target *i_CpuTarget,
return l_errl;
}
+
+/**
+ * @brief apply cpu reg information to the SLW image using
+ * p8_pore_gen_cpureg() .
+ *
+ * @param io_image - pointer to the SLW image
+ * @param i_sizeImage - size of the SLW image
+ *
+ * @return errorlog if error, NULL otherwise.
+ *
+ * @todo $$ pore_gen_cpu_reg not supported this sprint (???), leave main code
+ * commented out for now.
+ * @todo $$ l_regname is defined as "unswizzled spr value" ????
+ */
+errlHndl_t applyPoreGenCpuRegs( TARGETING::Target *i_cpuTarget,
+ void *io_image,
+ uint32_t i_sizeImage )
+{
+ errlHndl_t l_errl = NULL;
+
+ TARGETING::TargetHandleList l_coreIds;
+ getChildChiplets( l_coreIds,
+ i_cpuTarget,
+ TYPE_CORE,
+ true );
+
+ TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "applyPoreGenCpuRegs: Process cores=0x%x, threads=0x%x",
+ l_coreIds.size(),
+ cpu_thread_count() );
+
+#if 1
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "applyPoreGenCpuRegs: DISABLED until pore_gen_cpureg integration" );
+
+ // $$ this will be turned on when we integrate pore_gen_cpureg
+ // $$ @todo RTC 41425
+#else
+ size_t l_threadid = 0;
+ size_t l_coreid = 0;
+ uint32_t l_rc = 0;
+ uint64_t l_msrcVal = cpu_spr_value(CPU_SPR_MSRC) ;
+ uint64_t l_lpcrVal = cpu_spr_value(CPU_SPR_LPCR) ;
+ uint64_t l_hrmorVal = cpu_spr_value(CPU_SPR_HRMOR);
+ for ( l_coreid=0; l_coreid < l_coreIds.size(); l_coreid++ )
+ {
+ for ( l_threadid=0; l_threadid < cpu_thread_count(); l_threadid++ )
+ {
+
+ TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "core=0x%x,thread=0x%x: ",
+ l_coreid,
+ l_threadid );
+ TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "msrc=0x%x,lpcr=0x%x,hrmor=0x%x",
+ l_msrcVal,
+ l_lpcrVal,
+ l_hrmorVal );
+ do {
+ l_rc = p8_pore_gen_cpureg( io_image,
+ i_sizeImage,
+ l_regName,
+ l_msrcVal,
+ l_coreid,
+ l_threadid);
+ if ( l_rc )
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "p8_pore_gen_cpu_reg ERROR: MSRC: core=0x%x,thread=0x%x,l_rc=0x%x",
+ l_coreId,
+ l_threadId,
+ l_rc );
+ break;
+ }
+
+ l_rc = p8_pore_gen_cpureg( io_image,
+ i_sizeImage,
+ l_regName,
+ l_lpcrVal,
+ l_coreid,
+ l_threadid);
+ if ( l_rc )
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "p8_pore_gen_cpu_reg ERROR: LPCR: core=0x%x,thread=0x%x,l_rc=0x%x",
+ l_coreId,
+ l_threadId,
+ l_rc );
+ break;
+ }
+
+ l_rc = p8_pore_gen_cpureg( io_image,
+ i_sizeImage,
+ l_regName,
+ l_hrmorVal,
+ l_coreid,
+ l_threadid);
+ if ( l_rc ){
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "p8_pore_gen_cpu_reg ERROR: HRMOR: core=0x%x,thread=0x%x,l_rc=0x%x",
+ l_coreId,
+ l_threadId,
+ l_rc );
+ break;
+ }
+
+
+ } while (0);
+
+ if ( l_rc ){
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "p8_pore_gen_cpu_reg ERROR: core=0x%x, thread=0x%x, l_rc=0x%x",
+ l_coreId,
+ l_threadId,
+ l_rc );
+ /*@
+ * @errortype
+ * @reasoncode ISTEP_BAD_RC
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid ISTEP_BUILD_WINKLE_IMAGES
+ * @userdata1 return code from p8_pore_gen_cpureg
+ *
+ * @devdesc p8_pore_gen_cpureg returned an error when
+ * attempting to change a reg value in the PORE image.
+ */
+ l_errl =
+ new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ ISTEP_BUILD_WINKLE_IMAGES,
+ ISTEP_BAD_RC,
+ l_rc );
+ }
+ } // end for l_threadId
+ } // end for l_coreId
+#endif
+
+ return l_errl;
+}
+
//
// Wrapper function to call 15.1 :
// host_build_winkle
@@ -159,40 +296,33 @@ errlHndl_t loadPoreImage( TARGETING::Target *i_CpuTarget,
void call_host_build_winkle( void *io_pArgs )
{
errlHndl_t l_errl = NULL;
- uint8_t l_cpuNum = 0;
const char *l_pPoreImage = NULL;
size_t l_poreSize = 0;
void *l_pImageOut = NULL;
uint32_t l_sizeImageOut = MAX_OUTPUT_PORE_IMG_SIZE;
-
TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
"call_host_build_winkle entry" );
// @@@@@ CUSTOM BLOCK: @@@@@
- // figure out what targets we need
- // customize any other inputs
- // set up loops to go through all targets (if parallel, spin off a task)
-
+ // find the master core, i.e. the one we are running on
+ TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Find master chip: " );
- TARGETING::TargetHandleList l_cpuTargetList;
- getAllChips(l_cpuTargetList, TYPE_PROC);
+ const TARGETING::Target* l_masterCore = getMasterCore( );
+ assert( l_masterCore != NULL );
- for ( l_cpuNum=0; l_cpuNum < l_cpuTargetList.size(); l_cpuNum++ )
- {
- // make a local copy of the CPU target
- TARGETING::Target* l_cpu_target = l_cpuTargetList[l_cpuNum];
+ TARGETING::Target* l_cpu_target = const_cast<TARGETING::Target *>
+ ( getParentChip( l_masterCore ) );
- TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "Run cpuNum 0x%x",
- l_cpuNum );
+ // dump physical path to target
+ EntityPath l_path;
+ l_path = l_cpu_target->getAttr<ATTR_PHYS_PATH>();
+ l_path.dump();
- // dump physical path to target
- EntityPath l_path;
- l_path = l_cpu_target->getAttr<ATTR_PHYS_PATH>();
- l_path.dump();
+ do {
l_errl = loadPoreImage( l_cpu_target,
l_pPoreImage,
@@ -205,20 +335,29 @@ void call_host_build_winkle( void *io_pArgs )
// drop out of loop and return errlog to fail.
break;
}
-
- // cast OUR type of target to a FAPI type of target.
- const fapi::Target l_fapi_cpu_target(
- TARGET_TYPE_PROC_CHIP,
- reinterpret_cast<void *>
- (const_cast<TARGETING::Target*>(l_cpu_target)) );
-
//
- // stub - get address of output buffer for PORE image for this CPU,
- // and load it there
+ // @todo stub - eventually this will make a system call to get storage
+ // ( and size ) for the output buffer for PORE image for this CPU.
+ // Save the results in attributes so that other isteps/substeps can
+ // use it.
//
- l_pImageOut = g_pOutputPoreImg;
+ // @NOTE NOTE NOTE
+ // This address must be on a 1-meg boundary.
+ //
+ l_pImageOut = reinterpret_cast<void * const >(OUTPUT_PORE_IMG_ADDR);
+ l_cpu_target->setAttr<TARGETING::ATTR_SLW_IMAGE_ADDR>
+ ( OUTPUT_PORE_IMG_ADDR );
+
l_sizeImageOut = MAX_OUTPUT_PORE_IMG_SIZE;
+ l_cpu_target->setAttr<TARGETING::ATTR_SLW_IMAGE_SIZE>
+ ( MAX_OUTPUT_PORE_IMG_SIZE );
+ // cast OUR type of target to a FAPI type of target.
+ const fapi::Target l_fapi_cpu_target(
+ TARGET_TYPE_PROC_CHIP,
+ reinterpret_cast<void *>
+ (const_cast<TARGETING::Target*>
+ (l_cpu_target)) );
// call the HWP with each fapi::Target
FAPI_INVOKE_HWP( l_errl,
@@ -244,7 +383,25 @@ void call_host_build_winkle( void *io_pArgs )
l_sizeImageOut );
}
- } // endfor
+ // set the actual size of the image now.
+ l_cpu_target->setAttr<TARGETING::ATTR_SLW_IMAGE_SIZE>
+ ( l_sizeImageOut );
+
+ // apply the cpu reg information to the image.
+ l_errl = applyPoreGenCpuRegs( l_cpu_target,
+ l_pImageOut,
+ l_sizeImageOut );
+ if ( l_errl )
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "applyPoreGenCpuRegs ERROR : Returning errorlog, PLID=0x%x",
+ l_errl->plid() );
+ // drop out if we hit an error and quit.
+ break;
+ }
+
+ } while (0); // end do block
+
// @@@@@ END CUSTOM BLOCK: @@@@@
@@ -263,43 +420,96 @@ void call_host_build_winkle( void *io_pArgs )
//
void call_proc_set_pore_bar( void *io_pArgs )
{
- errlHndl_t l_errl = NULL;
+ errlHndl_t l_errl = NULL;
TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
"call_proc_set_pore_bar entry" );
-#if 0
// @@@@@ CUSTOM BLOCK: @@@@@
- // figure out what targets we need
- // customize any other inputs
- // set up loops to go through all targets (if parallel, spin off a task)
- // dump physical path to targets
+ const TARGETING::Target* l_masterCore = TARGETING::getMasterCore( );
+ assert( l_masterCore != NULL );
+
+ TARGETING::Target* l_cpu_target = const_cast<TARGETING::Target *>
+ ( getParentChip( l_masterCore ) );
+
+ // dump physical path to target
EntityPath l_path;
- l_path = l_@targetN_target->getAttr<ATTR_PHYS_PATH>();
+ l_path = l_cpu_target->getAttr<ATTR_PHYS_PATH>();
l_path.dump();
- // cast OUR type of target to a FAPI type of target.
- const fapi::Target l_fapi_@targetN_target(
- TARGET_TYPE_MEMBUF_CHIP,
- reinterpret_cast<void *>
- (const_cast<TARGETING::Target*>(l_@targetN_target)) );
+ do {
- // call the HWP with each fapi::Target
- FAPI_INVOKE_HWP( l_errl, proc_set_pore_bar, _args_...);
- if ( l_errl )
- {
- TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
- "ERROR : .........." );
- errlCommit( l_errl, HWPF_COMP_ID );
- }
- else
- {
+ // fetch image location and size, written by host_build_winkle above
+
+ // Note that the "i_mem_bar" input to proc_set_pore_bar is the physical
+ // address of the PORE image, this is the image that will get executed
+ // at winkle. The void * i_image parameter actually points to the same
+ // place in HostBoot; in fsp or cronus these will be different.
+ //
+ // @todo this may change for secure boot, need to make up an RTC
+ // to handle this, or there may one already???
+ //
+ uint64_t l_imageAddr =
+ l_cpu_target->getAttr<TARGETING::ATTR_SLW_IMAGE_ADDR>();
+
+
+ // $$ @todo the hardware wants a mask to cover the size of the image,
+ // with the added proviso that the lower 5 nybbles of the mask must
+ // always be 0.
+ // Thus, as long as the image is under 1M, this value will be 0 .
+ // The HWP guys will probably pull this calculation inside
+ // proc_set_pore_bar() so that we just specify the size in bytes.
+ // This comment will be left until we integrate the new version.
+ // In the meantime, l_mem_mask should be set to 0 to work correctly.
+ uint64_t l_mem_mask = 0;
+
+ // defined in proc_set_pore_bar.H
+ uint32_t l_mem_type = SLW_L3 ;
+
+ // cast OUR type of target to a FAPI type of target.
+ const fapi::Target l_fapi_cpu_target(
+ TARGET_TYPE_PROC_CHIP,
+ reinterpret_cast<void *>
+ (const_cast<TARGETING::Target*>
+ (l_cpu_target)) );
+
+ // call the HWP with each fapi::Target
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "SUCCESS : .........." );
- }
+ "Call proc_set_pore_bar, membar=0x%lx, size=0x%lx, mask=0x%lx, type=0x%x",
+ l_imageAddr,
+ (l_cpu_target->getAttr<ATTR_SLW_IMAGE_SIZE>()),
+ l_mem_mask,
+ l_mem_type );
+
+
+ void * const l_pImage = reinterpret_cast<void * const>(l_imageAddr);
+
+ FAPI_INVOKE_HWP( l_errl,
+ proc_set_pore_bar,
+ l_fapi_cpu_target,
+ l_pImage,
+ l_imageAddr,
+ l_mem_mask,
+ l_mem_type
+ );
+
+ if ( l_errl )
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "ERROR : proc_set_pore_bar, PLID=0x%x",
+ l_errl->plid() );
+ }
+ else
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "SUCCESS : proc_set_pore_bar" );
+ }
+
+ } while ( 0 ); // end do block
+
// @@@@@ END CUSTOM BLOCK: @@@@@
-#endif
+
TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
"call_proc_set_pore_bar exit" );
diff --git a/src/usr/hwpf/hwp/build_winkle_images/makefile b/src/usr/hwpf/hwp/build_winkle_images/makefile
index c970dfd84..815db6200 100644
--- a/src/usr/hwpf/hwp/build_winkle_images/makefile
+++ b/src/usr/hwpf/hwp/build_winkle_images/makefile
@@ -41,6 +41,9 @@ EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/build_winkle_images
## EXAMPLE:
## EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/build_winkle_images/<HWP_dir>
EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build
+EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/build_winkle_images/proc_set_pore_bar
+EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/build_winkle_images/proc_pba_bar_config
+EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/build_winkle_images/pore_gen_cpureg
CUSTOMFLAGS+= -D __FAPI
@@ -52,15 +55,20 @@ OBJS = build_winkle_images.o \
p8_scan_compression.o \
pore_inline_assembler.o \
proc_slw_build.o \
- sbe_xip_image.o
+ sbe_xip_image.o \
+ proc_set_pore_bar.o \
+ proc_pba_bar_config.o
## NOTE: add a new directory onto the vpaths when you add a new HWP
## EXAMPLE:
# VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/build_winkle_images/<HWP_dir>
VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build
+VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/build_winkle_images/proc_set_pore_bar
+VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/build_winkle_images/proc_pba_bar_config
+VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/build_winkle_images/pore_gen_cpureg
## Point to the PORE image in PNOR
-BINARY_FILES = $(IMGDIR)/procpore.dat:1f6e49c91e2a2b0df5fad6c215c8f09d9f19fce6
+BINARY_FILES = $(IMGDIR)/procpore.dat:72cc5bef88f4d55dd9bbc9ad096e7dacff7d46e4
include ${ROOTPATH}/config.mk
diff --git a/src/usr/hwpf/hwp/build_winkle_images/pore_gen_cpureg/HvPlicModule.H b/src/usr/hwpf/hwp/build_winkle_images/pore_gen_cpureg/HvPlicModule.H
new file mode 100644
index 000000000..859c217cd
--- /dev/null
+++ b/src/usr/hwpf/hwp/build_winkle_images/pore_gen_cpureg/HvPlicModule.H
@@ -0,0 +1,24 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/hwpf/hwp/build_winkle_images/pore_gen_cpureg/HvPlicModule.H $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
+
diff --git a/src/usr/hwpf/hwp/build_winkle_images/pore_gen_cpureg/p8_pore_table_gen_api.H b/src/usr/hwpf/hwp/build_winkle_images/pore_gen_cpureg/p8_pore_table_gen_api.H
new file mode 100644
index 000000000..e78a31e7a
--- /dev/null
+++ b/src/usr/hwpf/hwp/build_winkle_images/pore_gen_cpureg/p8_pore_table_gen_api.H
@@ -0,0 +1,286 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/hwpf/hwp/build_winkle_images/pore_gen_cpureg/p8_pore_table_gen_api.H $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
+/*------------------------------------------------------------------------------*/
+/* *! (C) Copyright International Business Machines Corp. 2012 */
+/* *! All Rights Reserved -- Property of IBM */
+/* *! *** IBM Confidential *** */
+/*------------------------------------------------------------------------------*/
+/* *! TITLE : p8_pore_table_gen_api */
+/* *! DESCRIPTION : Contains all external APIs used by firmware (PHYP) to */
+// generate/modify the P8 PORE SLW image with /Ramming and
+// Scomming specific instructions to be executed on exit from
+// Sleep/Winkle. Also contains definitions for the ramming
+// PORE code.
+/* *! OWNER NAME : Michael Olsen Email: cmolsen@us.ibm.com */
+//
+/* *! COMMENTS : *** VERY IMPORTANT *** */
+// The "Shared RAM section", the "Pore RAM section" and the
+// "C-code RAM section" must closely match eachother.
+//
+/*------------------------------------------------------------------------------*/
+
+#ifndef _P8_PORE_TABLE_GEN_API_H
+#define _P8_PORE_TABLE_GEN_API_H
+
+/********************************************************************/
+/* Shared RAM section - begin */
+/* This section MUST perfectly match the "Pore/C-code RAM section". */
+/********************************************************************/
+// Header defs (P8&PORE 64-bit notation where bits are numbered from left-to-right).
+// (Some of these defs are used in the c-specific section further down.)
+// -----------------------------------------------------------------------------
+// Note: SPR register numbers have a swizzle about them per PPC architecture
+// spr(instruction) <- spr5:9 || spr0:4
+//
+// For the PGAS routine, it is assumed that the API does the swizzling upon
+// building the instruction held in this structure
+//
+// Header configuration: CPU Register Operation Header
+// 0 - End: 1=End; 0=More
+// 1 - Reserved
+// 2:3 - Type
+// 00: MTSPR
+// 01: MTGPR
+// 10: Reserved
+// 11: Reserved
+// 4:13 - SPR number in non-swizzled form (0:9)
+// 14:15 - Reserved for SPR nunmber expansion
+// 16:18 - Thread ID
+// 19:31 - Reserved
+
+#define RAM_HEADER_END_START 0
+#define RAM_HEADER_END_MASK BITS(RAM_HEADER_END_START,1)
+#define RAM_HEADER_TYPE_START 2
+#define RAM_HEADER_TYPE_MASK BITS(RAM_HEADER_TYPE_START,2)
+#define RAM_HEADER_SPRN_START 4
+#define RAM_HEADER_SPRN_MASK BITS(RAM_HEADER_SPRN_START,10)
+#define RAM_HEADER_THREAD_START 16
+#define RAM_HEADER_THREAD_MASK BITS(RAM_HEADER_THREAD_START,3)
+#define RAM_INSTR_START 32
+#define RAM_INSTR_MASK BITS(RAM_INSTR_START,32)
+// MTSPR instr defs
+#define RAM_MTSPR_INSTR_TEMPL ( ( (uint64_t)31<<(63-5) | (uint64_t)467<<(63-30) ) )
+#define RAM_MTSPR_SPR_START 11
+#define RAM_MTSPR_SPR_MASK BITS(RAM_MTSPR_SPR_START,10)
+// Thread align defs
+#define RAM_HEADER_THREAD_RALIGN ( 61-16 ) // 3 Bit shift right amount
+#define RAM_HEADER_THREAD_LALIGN ( 61-16 ) // 3 Bit shift left amount
+/********************************************************************/
+/* Shared RAM section - end */
+/********************************************************************/
+
+
+#ifdef FOR_PORE_RAMMING
+
+// Thread status
+CONST_UINT64_T( PROC_RAS_STAT_10013002 , ULL(0x10013002) );
+
+// TCTL RAS Status (for each thread)
+// Note: the address is not included in the name to ease PGAS indexing
+// of these registers
+CONST_UINT64_T( EX_PERV_TCTL0_R_STAT , ULL(0x10013002) );
+CONST_UINT64_T( EX_PERV_TCTL1_R_STAT , ULL(0x10013012) );
+CONST_UINT64_T( EX_PERV_TCTL2_R_STAT , ULL(0x10013022) );
+CONST_UINT64_T( EX_PERV_TCTL3_R_STAT , ULL(0x10013032) );
+CONST_UINT64_T( EX_PERV_TCTL4_R_STAT , ULL(0x10013042) );
+CONST_UINT64_T( EX_PERV_TCTL5_R_STAT , ULL(0x10013052) );
+CONST_UINT64_T( EX_PERV_TCTL6_R_STAT , ULL(0x10013062) );
+CONST_UINT64_T( EX_PERV_TCTL7_R_STAT , ULL(0x10013072) );
+
+// Thread scratch registers
+// Note: the address is not included in the name to ease PGAS indexing
+// of these registers
+CONST_UINT64_T( EX_PERV_SCRATCH0 , ULL(0x10013283) );
+CONST_UINT64_T( EX_PERV_SCRATCH1 , ULL(0x10013284) );
+CONST_UINT64_T( EX_PERV_SCRATCH2 , ULL(0x10013285) );
+CONST_UINT64_T( EX_PERV_SCRATCH3 , ULL(0x10013286) );
+CONST_UINT64_T( EX_PERV_SCRATCH4 , ULL(0x10013287) );
+CONST_UINT64_T( EX_PERV_SCRATCH5 , ULL(0x10013288) );
+CONST_UINT64_T( EX_PERV_SCRATCH6 , ULL(0x10013289) );
+CONST_UINT64_T( EX_PERV_SCRATCH7 , ULL(0x1001328A) );
+
+// Max # of polling attempts. SLW ops have no quiescent needs, so low #.
+CONST_UINT32_T( SLW_MAX_RAM_POLLS , ULL(0x04) );
+
+// mfspr gpr0, scratch0 opcode left-shifted 29 bits, ready for ramming.
+CONST_UINT64_T( MFSPR_GPR0_SCRATCH0_RAM_READY, (0x000000007C1542A6<<29));
+
+#ifdef __ASSEMBLER__
+
+/***********************************************************************/
+/* Pore RAM section - begin */
+/* This section MUST perfectly match the "Shared/C-code RAM section". */
+/***********************************************************************/
+.set RAM_HEADER, 0
+.set RAM_INSTR, 4
+.set RAM_DATA, 8
+.set RAM_ENTRY_LENGTH, 16
+/***********************************************************************/
+/* Pore RAM section - end */
+/***********************************************************************/
+
+#endif // __ASSEMBLER__
+
+
+#else // Not FOR_PORE_RAMMING
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+
+#include "pore_bitmanip.H"
+
+// Header defs (C notation where bits are numbered from right-to-left, and reducing to 32-bit)
+#define RAM_HEADER_END_START_C ( 31-RAM_HEADER_END_START+1-1 )
+#define RAM_HEADER_END_MASK_C (uint32_t)(RAM_HEADER_END_MASK>>32)
+#define RAM_HEADER_TYPE_START_C ( 31-RAM_HEADER_TYPE_START+1-2 )
+#define RAM_HEADER_TYPE_MASK_C (uint32_t)(RAM_HEADER_TYPE_MASK>>32)
+#define RAM_HEADER_SPRN_START_C ( 31-RAM_HEADER_SPRN_START+1-10 )
+#define RAM_HEADER_SPRN_MASK_C (uint32_t)(RAM_HEADER_SPRN_MASK>>32)
+#define RAM_HEADER_THREAD_START_C ( 31-RAM_HEADER_THREAD_START+1-3 )
+#define RAM_HEADER_THREAD_MASK_C (uint32_t)(RAM_HEADER_THREAD_MASK>>32)
+// MTSPR instr defs
+#define RAM_MTSPR_INSTR_TEMPL_C ( ( (uint32_t)31<<(31-5) | (uint32_t)467<<(31-30) ) )
+#define RAM_MTSPR_SPR_START_C ( 31-RAM_MTSPR_SPR_START+1-10 )
+//#define RAM_MTSPR_SPR_MASK_C (uint32_t)(BITS(RAM_MTSPR_SPR_START,10)>>32)
+#define RAM_MTSPR_SPR_MASK_C (uint32_t)(RAM_MTSPR_SPR_MASK>>32)
+
+/* Other defs needed for ramming */
+// TOC names
+#define SLW_HOST_REG_VECTOR_TOC_NAME "slw_host_reg_vector"
+#define SLW_HOST_SCOM_VECTOR_TOC_NAME "slw_host_scom_vector"
+#define SLW_HOST_REG_TABLE_TOC_NAME "slw_core_reg_table"
+
+// Defines for slw_build() to update "host_runtime_scom" w/pointer to "sub_slw_runtime_scom" at SLW image build time.
+#define HOST_RUNTIME_SCOM_TOC_NAME "host_runtime_scom" // Null 1st, then fill w/addr of SLW_RUNTIME_SCOM_TOC_NAME
+#define SLW_RUNTIME_SCOM_TOC_NAME "sub_slw_runtime_scom"
+
+// RAM table defines
+#define XIPSIZE_RAM_ENTRY ( (sizeof(RamTableEntry)+7)/8*8 )
+#define SLW_MAX_CORES 16
+#define SLW_MAX_CPUREGS_CORE 8
+#define SLW_MAX_CPUREGS_THREADS 2 // Was 3 at some point, when MSR reg was included?
+#define SLW_CORE_THREADS 8
+#define SLW_MAX_CPUREGS_OPS ( SLW_MAX_CPUREGS_CORE + \
+ SLW_CORE_THREADS*SLW_MAX_CPUREGS_THREADS )
+// $$ mww 2012-07-19 SLW_SLW_SECTION_SIZE removed? needed by proc_slw_build
+#define SLW_SLW_SECTION_SIZE ( SLW_MAX_CORES * SLW_MAX_CPUREGS_OPS * XIPSIZE_RAM_ENTRY )
+#define SLW_RAM_TABLE_SIZE ( SLW_MAX_CORES * SLW_MAX_CPUREGS_OPS * XIPSIZE_RAM_ENTRY )
+
+// SCOM table defines
+#define XIPSIZE_SCOM_ENTRY 16
+#define SLW_MAX_SCOMS 32
+#define SLW_SCOM_TABLE_SPACE_PER_CORE ( (SLW_MAX_SCOMS+1)*XIPSIZE_SCOM_ENTRY ) // Add 1 for RNNN IIS
+#define SLW_SCOM_TABLE_SIZE ( SLW_MAX_CORES * SLW_SCOM_TABLE_SPACE_PER_CORE )
+
+// SCOM/CID masks and ranges
+#define P8_CID_EX_LOW 0x10 // Lowest EX chiplet addr
+#define P8_CID_EX_HIGH 0x1f // Highest EX chiplet addr
+
+// SCOM Operators
+#define P8_PORE_SCOM_FIRST_OP 1 // First supported INPUT Scom operation.
+#define P8_PORE_SCOM_APPEND 0 // Add Scom to the end of table (only used internally)
+#define P8_PORE_SCOM_REPLACE 1 // Replace existing Scom, or append to end of table
+#define P8_PORE_SCOM_OR 2 // Overlay data onto existing Scom by bitwise OR
+#define P8_PORE_SCOM_AND 3 // Overlay data onto existing Scom by bitwise AND
+#define P8_PORE_SCOM_NOOP 4 // Replace existing Scom PORE NOP instruction
+#define P8_PORE_SCOM_RESET 5 // Delete all entries for given coreID. Repl w/RNNN IIS
+#define P8_PORE_SCOM_LAST_OP 5 // Keep track of the last op for checking correctness of op input
+
+
+// Return codes
+#define SLW_RAM_SUCCESS 0
+#define SLW_RAM_HEADERS_NOT_SYNCED 1
+#define SLW_RAM_IMAGE_SIZE_MISMATCH 2
+#define SLW_RAM_TABLE_ENTRY_OVERFLOW 3
+#define SLW_RAM_CODE_ERROR 4
+#define SLW_RAM_INVALID_PARAMETER 5
+#define SLW_RAM_WARNING_TABLE_CONTAMINATION 6
+
+
+#ifdef __cpluscplus
+extern "C" {
+#endif
+
+/********************************************************************/
+/* C-code RAM section - begin */
+/* This section MUST perfectly match the "Shared/Pore RAM section". */
+/********************************************************************/
+typedef struct ram_instr_t {
+ uint32_t header;
+ uint32_t instr;
+ uint64_t data;
+} RamTableEntry;
+/********************************************************************/
+/* C-code RAM section - end */
+/********************************************************************/
+
+// SLW supported SPR registers
+typedef struct {
+ const char *name;
+ uint32_t value;
+ uint32_t swizzled;
+} SlwSprRegs;
+
+
+/* Name: p8_pore_gen_cpureg()
+ * Description: Populates ramming entries in the .slw section
+ * Parameter list: i_image - pointer to SLW mainstore image
+ * i_sizeImage - size of SLW mainstore image
+ * i_regName - unswizzled SPR register value
+ * i_regData - data to write to SPR register
+ * i_coreId - the core ID to operate on
+ * i_threadId - the thread ID to operate on
+ */
+uint32_t p8_pore_gen_cpureg(void *io_image,
+ uint32_t i_sizeImage,
+ uint32_t i_regName,
+ uint64_t i_regData,
+ uint32_t i_coreId,
+ uint32_t i_threadId);
+
+/* Name: p8_pore_gen_scom()
+ * Description: Populates scom entries in the .slw section
+ * Parameter list: i_image - pointer to SLW mainstore image
+ * i_sizeImage - size of SLW mainstore image
+ * i_scomAddr - scom register address
+ * i_scomData - 64-bit data to put in scom register
+ * i_operation - what to do with the scom data
+ * i_coreId - the core ID [0:15]
+ */
+uint32_t p8_pore_gen_scom(void *io_image,
+ uint32_t i_sizeImage,
+ uint32_t i_scomAddr,
+ uint32_t i_coreId,
+ uint64_t i_scomData,
+ uint32_t i_operation);
+
+#ifdef __cpluscplus
+}
+#endif
+
+#endif // FOR_PORE_RAMMING
+
+#endif // _P8_PORE_TABLE_GEN_API_H
diff --git a/src/usr/hwpf/hwp/build_winkle_images/proc_pba_bar_config/proc_pba_bar_config.C b/src/usr/hwpf/hwp/build_winkle_images/proc_pba_bar_config/proc_pba_bar_config.C
new file mode 100644
index 000000000..72eff97b2
--- /dev/null
+++ b/src/usr/hwpf/hwp/build_winkle_images/proc_pba_bar_config/proc_pba_bar_config.C
@@ -0,0 +1,254 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/hwpf/hwp/build_winkle_images/proc_pba_bar_config/proc_pba_bar_config.C $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
+// $Id: proc_pba_bar_config.C,v 1.6 2012/05/23 15:22:10 stillgs Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/proc_pba_bar_config.C,v $
+//------------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2011
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//------------------------------------------------------------------------------
+// *! OWNER NAME: Klaus P. Gungl Email: kgungl@de.ibm.com
+// *!
+// *!
+/// \file proc_pba_bar_config.C
+/// \brief Initialize PAB and PAB_MSK of PBA
+// *!
+// *! The purpose of this procedure is to set the PBA BAR, PBA BAR Mask and PBA scope value / registers
+// *!
+// *! Following proposals here: pass values for one set of pbabar, pass reference to structure for one set of pbabar, pass struct of struct containing
+// *! all setup values
+// *!
+// *! High-level procedure flow:
+// *! parameter checking
+// *! set PBA_BAR
+// *! set PBA_BARMSK
+// *!
+// *! Procedure Prereq:
+// *! o System clocks are running
+// *!
+// *! list of changes
+// *! 2011/11/22 all variables / passing calling parameters are uint64_t, cmd_scope is enum, MASK is not bitmask parameter but size
+// *! structure for init contain uint64_t only.
+// *!
+//------------------------------------------------------------------------------
+
+
+// ----------------------------------------------------------------------
+// Includes
+// ----------------------------------------------------------------------
+#include <fapi.H>
+#include "p8_scom_addresses.H"
+#include "proc_pba_init.H"
+#include "proc_pba_bar_config.H"
+#include "proc_pm.H"
+
+
+extern "C" {
+
+
+using namespace fapi;
+
+// ----------------------------------------------------------------------
+// Constant definitions
+// ----------------------------------------------------------------------
+
+// for range checking 0x0123456701234567
+#define BAR_ADDR_RANGECHECK_ 0x0003FFFFFFF00000ull
+#define BAR_ADDR_RANGECHECK_HIGH 0xFFFC000000000000ull
+#define BAR_ADDR_RANGECHECK_LOW 0x00000000000FFFFFull
+#define BAR_MASK_RANGECHECK 0x000001FFFFF00000ull
+#define BAR_MASK_RANGECHECK_HIGH 0xFFFFFE0000000000ull
+#define BAR_MASK_RANGECHECK_LOW 0x00000000000FFFFFull
+
+// ----------------------------------------------------------------------
+// Global variables
+// ----------------------------------------------------------------------
+
+// ----------------------------------------------------------------------
+// Prototypes
+// ----------------------------------------------------------------------
+
+// ----------------------------------------------------------------------
+// Function definitions
+// ----------------------------------------------------------------------
+
+// --------------------------------------------- proc_pba_bar_config ----
+// function:
+// initialize initialize a specific set of PBA_BAR (=cmd_scope and address), PBA_BARMSK (mask/size)
+// pass values directly
+//! init_pba_bar_ps
+//! initialize a set of PBA_BAR and PBA_BARMSK registers, calling parameters: reference to structure of initialization values
+/*!
+@param i_target the target
+@param i_index specifies which set of BAR / BARMSK registers to set. [0..3]
+@param i_pba_bar_addr PBA base address - 1MB grandularity
+@param i_pba_bar_mask PBA base address mask that defines the bits that are not used from the PBA base address - 1MB grandularity
+ The value of this mask + 1 defines the size of the window that is accessible.
+ (ex. 700000 yields an 8MB region)
+@param i_pba_cmd_scope command scope according to pba spec
+*/
+
+fapi::ReturnCode
+proc_pba_bar_config (const Target& i_target,
+ uint32_t i_index,
+ uint64_t i_pba_bar_addr,
+ uint64_t i_pba_bar_mask,
+ uint64_t i_pba_cmd_scope
+ )
+{
+
+ // Define structures that map the register fields
+
+ typedef union pba_barn {
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t cmd_scope : 3;
+ uint64_t reserved0 : 1;
+ uint64_t reserved1 : 10;
+ uint64_t addr : 50;
+#else
+ uint64_t addr : 50;
+ uint64_t reserved1 : 10;
+ uint64_t reserved0 : 1;
+ uint64_t cmd_scope : 3;
+#endif // _BIG_ENDIAN
+ } fields;
+ } pba_barn_t;
+
+
+ typedef union pba_barmskn {
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t reserved0 : 23;
+ uint64_t mask : 41;
+#else
+ uint64_t mask : 41;
+ uint64_t reserved0 : 23;
+#endif // _BIG_ENDIAN
+ } fields;
+ } pba_barmskn_t;
+
+
+
+ ecmdDataBufferBase data(64);
+ fapi::ReturnCode l_rc;
+ uint32_t l_ecmdRc = 0;
+
+ pba_barn_t bar;
+ pba_barmskn_t barmask;
+
+ FAPI_INF("Called with index %x, address 0x%16llX, mask 0x%16llX scope 0x%16llX",
+ i_index, i_pba_bar_addr, i_pba_bar_mask, i_pba_cmd_scope);
+
+ // check if pba_bar scope in range
+ if ( i_pba_cmd_scope > PBA_CMD_SCOPE_FOREIGN1 )
+ {
+ FAPI_ERR("ERROR: PB Command Scope out of Range");
+ FAPI_SET_HWP_ERROR(l_rc, RC_PROC_PBA_BAR_SCOPE_OUT_OF_RANGE);
+ return l_rc;
+ }
+
+ // check if pba_addr amd pba_mask are within range, high order bits checked, not low order!
+ // this means if we need a check for "is this value on the correct boundary value => needs to be implemented
+ if ( (BAR_ADDR_RANGECHECK_HIGH & i_pba_bar_addr) != 0x0ull)
+ {
+ FAPI_ERR("ERROR: Address out of Range");
+ FAPI_SET_HWP_ERROR(l_rc, RC_PROC_PBA_ADDR_OUT_OF_RANGE);
+ return l_rc;
+ }
+ if ( (BAR_MASK_RANGECHECK_HIGH & i_pba_bar_mask) != 0x0ull)
+ {
+ FAPI_ERR("ERROR: Mask out of Range");
+ FAPI_SET_HWP_ERROR(l_rc, RC_PROC_PBA_BAR_MASK_OUT_OF_RANGE);
+ return l_rc;
+ }
+
+ // put the parameters into the correct fields
+ bar.fields.cmd_scope = i_pba_cmd_scope;
+ bar.fields.addr = i_pba_bar_addr;
+ barmask.fields.mask = i_pba_bar_mask;
+
+ FAPI_INF("bar.fields address 0x%16llX, scope 0x%16llX",
+ bar.fields.addr, bar.fields.cmd_scope);
+
+ // Write the BAR
+ l_ecmdRc |= data.setDoubleWord(0, bar.value);
+ if (l_ecmdRc)
+ {
+ FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", l_ecmdRc);
+ l_rc.setEcmdError(l_ecmdRc);
+ return l_rc;
+ }
+
+// $$ FAPI_DBG(" PBA_BAR: %s", data.genHexLeftStr(0,64).c_str());
+ l_rc = fapiPutScom(i_target, PBA_BARs[i_index], data);
+ if(l_rc)
+ {
+ FAPI_ERR("PBA_BAR Putscom failed");
+ return l_rc;
+ }
+
+ // Write the MASK
+ l_ecmdRc |= data.setDoubleWord(0, barmask.value);
+ if (l_ecmdRc)
+ {
+ FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", l_ecmdRc);
+ l_rc.setEcmdError(l_ecmdRc);
+ return l_rc;
+ }
+
+// $$ FAPI_DBG(" PBA_BARMSK: %s", data.genHexLeftStr(0,64).c_str());
+ l_rc = fapiPutScom(i_target, PBA_BARMSKs[i_index], data);
+ if(l_rc)
+ {
+ FAPI_ERR("PBA_MASK Putscom failed");
+ return l_rc;
+ }
+
+ return l_rc;
+}
+
+
+} //end extern C
+
diff --git a/src/usr/hwpf/hwp/build_winkle_images/proc_pba_bar_config/proc_pba_bar_config.H b/src/usr/hwpf/hwp/build_winkle_images/proc_pba_bar_config/proc_pba_bar_config.H
new file mode 100644
index 000000000..f83f8a491
--- /dev/null
+++ b/src/usr/hwpf/hwp/build_winkle_images/proc_pba_bar_config/proc_pba_bar_config.H
@@ -0,0 +1,57 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/hwpf/hwp/build_winkle_images/proc_pba_bar_config/proc_pba_bar_config.H $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
+#
+
+//------------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2011
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//------------------------------------------------------------------------------
+// *! OWNER NAME: Klaus P. Gungl Email: kgungl@de.ibm.com
+// *!
+// *! General Description:
+// *!
+// *! include file for proc_pba_bar_config
+// *!
+//------------------------------------------------------------------------------
+//
+
+
+// function pointer typedef definition for HWP call support
+typedef fapi::ReturnCode (*proc_pba_bar_config_FP_t) (const fapi::Target&,
+ uint32_t,
+ uint64_t,
+ uint64_t,
+ uint64_t);
+
+extern "C"
+{
+
+fapi::ReturnCode
+proc_pba_bar_config (const fapi::Target& i_target,
+ uint32_t index,
+ uint64_t pba_bar_addr,
+ uint64_t pba_bar_mask,
+ uint64_t pba_cmd_scope);
+}
diff --git a/src/usr/hwpf/hwp/build_winkle_images/proc_pba_bar_config/proc_pba_bar_config_errors.xml b/src/usr/hwpf/hwp/build_winkle_images/proc_pba_bar_config/proc_pba_bar_config_errors.xml
new file mode 100644
index 000000000..d5c19db97
--- /dev/null
+++ b/src/usr/hwpf/hwp/build_winkle_images/proc_pba_bar_config/proc_pba_bar_config_errors.xml
@@ -0,0 +1,56 @@
+<!-- IBM_PROLOG_BEGIN_TAG
+ This is an automatically generated prolog.
+
+ $Source: src/usr/hwpf/hwp/build_winkle_images/proc_pba_bar_config/proc_pba_bar_config_errors.xml $
+
+ IBM CONFIDENTIAL
+
+ COPYRIGHT International Business Machines Corp. 2012
+
+ p1
+
+ Object Code Only (OCO) source materials
+ Licensed Internal Code Source Materials
+ IBM HostBoot Licensed Internal Code
+
+ The source code for this program is not published or other-
+ wise divested of its trade secrets, irrespective of what has
+ been deposited with the U.S. Copyright Office.
+
+ Origin: 30
+
+ IBM_PROLOG_END_TAG -->
+<!-- Error definitions for proc_pba_bar_config procedure -->
+<hwpErrors>
+ <!-- *********************************************************************** -->
+ <hwpError>
+ <rc>RC_PROC_PBA_BAR_INDEX_OUT_OF_RANGE</rc>
+ <description>pba bar index out of range, allowed is 0 to 3</description>
+ </hwpError>
+ <!-- *********************************************************************** -->
+ <hwpError>
+ <rc>RC_PROC_PBA_BAR_SCOPE_OUT_OF_RANGE</rc>
+ <description>pba bar scope out of range, allowed is 0 to 7</description>
+ </hwpError>
+ <!-- *********************************************************************** -->
+ <hwpError>
+ <rc>RC_PROC_PBA_ADDR_OUT_OF_RANGE</rc>
+ <description>pba bar scope out of range, allowed is 0 to 7</description>
+ </hwpError>
+ <!-- *********************************************************************** -->
+ <hwpError>
+ <rc>RC_PROC_PBA_BAR_MASK_OUT_OF_RANGE</rc>
+ <description>pba bar mask out of range. .</description>
+ </hwpError>
+ <!-- *********************************************************************** -->
+ <hwpError>
+ <rc>RC_PROC_PBA_BAR_MODE_NOT_SUPPORTED</rc>
+ <description>pba bar procedure mode is not supported .</description>
+ </hwpError>
+ <!-- *********************************************************************** -->
+ <hwpError>
+ <rc>RC_PROC_PBA_BAR_PUTSCOM_FAILED</rc>
+ <description>pba bar putscom failed .</description>
+ </hwpError>
+ <!-- *********************************************************************** -->
+</hwpErrors>
diff --git a/src/usr/hwpf/hwp/build_winkle_images/proc_set_pore_bar/proc_pba_init.H b/src/usr/hwpf/hwp/build_winkle_images/proc_set_pore_bar/proc_pba_init.H
new file mode 100644
index 000000000..7cbffb392
--- /dev/null
+++ b/src/usr/hwpf/hwp/build_winkle_images/proc_set_pore_bar/proc_pba_init.H
@@ -0,0 +1,209 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/hwpf/hwp/build_winkle_images/proc_set_pore_bar/proc_pba_init.H $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
+
+
+//------------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2011
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//------------------------------------------------------------------------------
+// *! OWNER NAME: Klaus P. Gungl Email: kgungl@de.ibm.com
+// *!
+// *! General Description:
+// *!
+// *! include file for pba_init with constants, definitions, prototypes
+// *!
+//------------------------------------------------------------------------------
+//
+
+#ifndef _PROC_PBAINIT_H_
+#define _PROC_PBAINIT_H_
+
+#include "p8_scom_addresses.H"
+
+typedef fapi::ReturnCode (*proc_pba_init_FP_t) (const fapi::Target& , uint64_t );
+
+// constant definitions for valid command scope. LIMIT is used by setup routine for plausibility checking.
+
+#define PBA_CMD_SCOPE_NODAL 0x00
+#define PBA_CMD_SCOPE_GROUP 0x01
+#define PBA_CMD_SCOPE_SYSTEM 0x02
+#define PBA_CMD_SCOPE_RGP 0x03
+#define PBA_CMD_SCOPE_FOREIGN0 0x04
+#define PBA_CMD_SCOPE_FOREIGN1 0x05
+#define PBA_CMD_SCOPE_LIMIT 0x06
+
+enum cmd_scope_t
+{
+ CMD_SCOPE_NODAL,
+ CMD_SCOPE_GROUP,
+ CMD_SCOPE_SYSTEM,
+ CMD_SCOPE_RGP,
+ CMD_SCOPE_FOREIGN0,
+ CMD_SCOPE_FOREIGN1
+};
+// enum cmd_scope_type {NODAL, GROUP, SYSTEM, RGP, FOREIGN0, FOREIGN1 };
+
+
+// addresses of PBA and PBABAR, actually a duplicate of definitions in "p8_scom_addresses.H" but here an array to be indexed.
+const uint64_t PBA_BARs[4] =
+{
+ PBA_BAR0_0x02013F00,
+ PBA_BAR1_0x02013F01,
+ PBA_BAR2_0x02013F02,
+ PBA_BAR3_0x02013F03
+};
+
+const uint64_t PBA_BARMSKs[4] =
+{
+ PBA_BARMSK0_0x02013F04,
+ PBA_BARMSK1_0x02013F05,
+ PBA_BARMSK2_0x02013F06,
+ PBA_BARMSK3_0x02013F07
+};
+
+const uint64_t PBA_SLVCTLs[4] =
+{
+ PBA_SLVCTL0_0x00064004,
+ PBA_SLVCTL1_0x00064005,
+ PBA_SLVCTL2_0x00064006,
+ PBA_SLVCTL3_0x00064007};
+
+// bar mask is valid for bits 23 to 43, in a 64bit value this is
+// 1 2 3 4 5 6
+// 0123456789012345678901234567890123456789012345678901234567890123
+// 0000000000000000000000011111111111111111111100000000000000000000
+// 0 0 0 0 0 1 F F F F F 0 0 0 0 0
+// 0000000000000011111111111111111111111111111100000000000000000000
+// 0 0 0 3 F F F F F F F 0 0 0 0 0
+// 0123456701234567
+#define BAR_MASK_LIMIT 0x000001FFFFF00000ull
+#define BAR_ADDR_LIMIT 0x0003FFFFFFF00000ull
+
+// structure of values for cmd_scope, pba and pbabar initialization
+typedef struct {
+ cmd_scope_t cmd_scope;
+ uint64_t addr;
+ uint64_t size;
+} struct_pba_bar_msk_scope_init_type;
+
+typedef struct {
+ struct_pba_bar_msk_scope_init_type regs0;
+ struct_pba_bar_msk_scope_init_type regs1;
+ struct_pba_bar_msk_scope_init_type regs2;
+ struct_pba_bar_msk_scope_init_type regs3;
+} pba_init_type;
+
+typedef struct {
+ unsigned long reserved_3:20;
+ unsigned long addr:30;
+ unsigned short reserved_2:10;
+ char reserved_1:1;
+ uint8_t cmd_scope:3;
+} struct_pba_bar_fields_type;
+
+typedef struct {
+ unsigned long reserved_1:23;
+ unsigned long mask:21;
+ unsigned long reserved_2:20;
+} struct_pba_barmsk_fields_type;
+
+typedef union {
+ struct_pba_bar_fields_type fields;
+ uint64_t value;
+} bar_reg_type;
+
+typedef union {
+ struct_pba_barmsk_fields_type fields ;
+ uint64_t value;
+} barmsk_reg_type;
+
+typedef struct {
+ bar_reg_type bar_reg;
+ barmsk_reg_type barmsk_reg;
+} struct_pba_bar_init_type;
+
+
+typedef struct {
+ struct struct_pba_bar{
+ char cmd_scope:3;
+ char reserved_1:1;
+ unsigned short reserved_2:10;
+ unsigned long addr:30;
+ unsigned long reserved_3:20;
+ };
+ struct struct_pba_barmsk{
+ unsigned long reserved_1:23;
+ unsigned long mask:21;
+ unsigned long reserved_2:20;
+ };
+} struct_pba_bar_init_type_1;
+
+typedef struct {
+ struct_pba_bar_init_type pba_bar0_init;
+ struct_pba_bar_init_type pba_bar1_init;
+ struct_pba_bar_init_type pba_bar2_init;
+ struct_pba_bar_init_type pba_bar3_init;
+} struct_all_pba_bar_init_type;
+
+
+typedef uint64_t pba_slvctl_type;
+
+
+typedef union pbaxcfg_typ{
+ uint64_t value;
+ struct {
+ unsigned long reserved_0 :20;
+ unsigned char ATTR_PM_PBAX_RCV_RESERV_TIMEOUT :5 ;
+ unsigned long reserved_1 :2;
+ unsigned char ATTR_PM_PBAX_SND_RETRY_COUNT_OVERCOMMIT_ENABLE :1 ;
+ unsigned short ATTR_PM_PBAX_SND_RETRY_THRESHOLD :8 ;
+ unsigned short ATTR_PM_PBAX_SND_RESERV_TIMEOUT :5 ;
+ unsigned long reserved_2 :23 ;
+ } fields;
+} pbaxcfg_t;
+
+
+
+
+// ----------------------------------------------------------------------
+// Function prototypes
+// ----------------------------------------------------------------------
+
+extern "C"
+{
+
+fapi::ReturnCode
+proc_pba_init (const fapi::Target& i_target,
+ uint64_t mode
+ );
+
+
+} // extern "C"
+
+
+
+#endif // _PROC_PBAINITQ_H_
+
+
diff --git a/src/usr/hwpf/hwp/build_winkle_images/proc_set_pore_bar/proc_pm.H b/src/usr/hwpf/hwp/build_winkle_images/proc_set_pore_bar/proc_pm.H
new file mode 100644
index 000000000..c65fb50a7
--- /dev/null
+++ b/src/usr/hwpf/hwp/build_winkle_images/proc_set_pore_bar/proc_pm.H
@@ -0,0 +1,74 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/hwpf/hwp/build_winkle_images/proc_set_pore_bar/proc_pm.H $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
+// $Id: proc_pm.H,v 1.4 2012/05/22 14:05:53 jimyac Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/proc_pm.H,v $
+//------------------------------------------------------------------------------
+// *|
+// *! (C) Copyright International Business Machines Corp. 2011
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+// *|
+// *! TITLE : proc_pm.H
+// *! DESCRIPTION : Common header for Power Manangement procedures
+// *!
+// *! OWNER NAME : Greg Still Email: stillgs@us.ibm.com
+// *! BACKUP NAME : Jim Yacynych Email: jimyac@us.ibm.com
+// *!
+//------------------------------------------------------------------------------
+
+#ifndef _PROC_PM_H_
+#define _PROC_PM_H_
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+
+#include <fapi.H>
+
+#include "p8_scom_addresses.H"
+
+
+extern "C" {
+
+//------------------------------------------------------------------------------
+// Constant definitions
+//------------------------------------------------------------------------------
+
+
+#ifndef _PROC_PM_FLOW_MODE
+#define _PROC_PM_FLOW_MODE
+enum PROC_PM_FLOW_MODE {
+ PM_CONFIG = 0x1,
+ PM_RESET = 0x2,
+ PM_INIT = 0x3,
+ PM_SETUP = 0x4,
+ PM_SETUP_PIB = 0x5,
+ PM_SETUP_ALL = 0x6
+ };
+#endif // _PROC_PM_FLOW_MODE
+
+
+} // extern "C"
+
+#endif // _PROC_PM_H_
diff --git a/src/usr/hwpf/hwp/build_winkle_images/proc_set_pore_bar/proc_set_pore_bar.C b/src/usr/hwpf/hwp/build_winkle_images/proc_set_pore_bar/proc_set_pore_bar.C
new file mode 100644
index 000000000..5e91313c1
--- /dev/null
+++ b/src/usr/hwpf/hwp/build_winkle_images/proc_set_pore_bar/proc_set_pore_bar.C
@@ -0,0 +1,463 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/hwpf/hwp/build_winkle_images/proc_set_pore_bar/proc_set_pore_bar.C $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
+// $Id: proc_set_pore_bar.C,v 1.7 2012/07/25 12:26:28 stillgs Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/proc_set_pore_bar.C,v $
+//------------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2011
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//------------------------------------------------------------------------------
+// *! OWNER NAME: Greg Still Email: stillgs@us.ibm.com
+// *!
+/// \file proc_set_pore_bar.C
+/// \brief Set up the Sleep/Winkle (SLW) PORE Memory Relocation (MRR) and
+/// Table Base Address (TBA) for accessing the SLW image
+///
+/// High-level procedure flow:
+/// \verbatim
+///
+/// Address and size of SLW image for the target (chip) is passed based on
+/// where the caller has placed the image for this target in the platform
+/// memory.
+///
+/// The Base Address (BAR) and a mask for the region in which the SLW
+/// image is placed is passed. This is used to establish the PBA BAR and
+/// mask hardware to set the legal bounds for SLW accesses.
+///
+/// The BAR defines address bits 14:43 in natural bit alignment (eg no shifting)
+/// The Mask defines validity for bits 23:43 in natural bit alignment. This
+/// is a "thermometer" mask to define a power of 2 size.
+///
+/// A "1" in the mask indicates that bit location comes from the SLW; a "0"
+/// indicates the bit comes from the BAR. Thus, the size of the region is
+/// ((mask+1)) MB. (eg the mask value 7 yields an 8MB region)
+///
+/// Check that passed address is within the 50 bit real address range
+/// Check that image address + image size does not extend past the 50 bit
+/// boundary
+///
+/// Read image link address at image offset 0x10
+/// Link Address(0:1) is the OCI region that will invoke the MRR. These
+/// are set into MRR(30:31).
+/// Calculate MRR address (32:63) = image address - link address (32 bit)
+/// Store MRR to PORE SLW
+///
+/// Call proc_pba_bar_config to set up PBA BAR 2 with the address and
+/// size of the SLW region as passed via calling parameters
+/// i_mem_bar and i_mem_mask.
+///
+/// Procedure Prereq:
+/// - SLW image memory region has been allocated and XIP image loaded.
+/// \endverbatim
+///
+//------------------------------------------------------------------------------
+
+
+// ----------------------------------------------------------------------
+// Includes
+// ----------------------------------------------------------------------
+#include <fapi.H>
+#include "p8_scom_addresses.H"
+#include "proc_set_pore_bar.H"
+#include "proc_pm.H"
+#include "proc_pba_init.H"
+#include "proc_pba_bar_config.H"
+#include "sbe_xip_image.h"
+
+
+extern "C" {
+
+using namespace fapi;
+
+// ----------------------------------------------------------------------
+// Constant definitions
+// ----------------------------------------------------------------------
+
+const uint32_t SLW_PBA_BAR = 2;
+
+// ----------------------------------------------------------------------
+// Global variables
+// ----------------------------------------------------------------------
+
+// ----------------------------------------------------------------------
+// Function prototypes
+// ----------------------------------------------------------------------
+
+// ----------------------------------------------------------------------
+// Function definitions
+// ----------------------------------------------------------------------
+
+
+/// \param[in] i_target Procesor Chip target
+/// \param[in] i_image Platform memory pointer where image is
+/// located
+/// \param[in] i_mem_bar Base address of the region where image is located
+/// \param[in] i_mem_mask Mask that defines which address bits of the
+/// BAR apply such to define the region size
+/// \param[in] i_mem_type Defines where the SLW image was loaded. See
+/// proc_set_pore_bar.H enum for valid values.
+///
+/// \retval SUCCESS
+/// \retval RC_PROCPM_POREBAR_IMAGE_BRANCH_VALUE_ERROR
+/// \retval RC_PROCPM_POREBAR_LOC_ERROR
+/// \retval RC_PROCPM_POREBAR_IMAGE_ADDR_ERROR (future version)
+/// \retval RC_PROCPM_POREBAR_IMAGE_PLACEMENT_ERROR (future version)
+
+fapi::ReturnCode
+proc_set_pore_bar( const fapi::Target& i_target,
+ void *i_image,
+ uint64_t i_mem_bar,
+ uint64_t i_mem_mask,
+ uint32_t i_mem_type)
+{
+ fapi::ReturnCode rc;
+ uint32_t l_ecmdRc = 0;
+ ecmdDataBufferBase data;
+
+ uint64_t image_address;
+ uint64_t image_size;
+// uint64_t region_begin_address;
+// uint64_t region_end_address;
+ uint64_t region_masked_address;
+// uint64_t region_inverted_mask;
+// uint64_t computed_image_address;
+// uint64_t computed_last_image_address;
+
+ uint64_t slw_branch_table_address;
+
+ // Hardcoded use of PBA BAR and Slave
+ const uint32_t pba_bar = PBA_BAR2;
+ const uint32_t pba_bar_slw = PBA_SLW_BAR2;
+ const uint32_t pba_slave = PBA_SLAVE2;
+
+ const uint64_t slw_pba_cmd_scope = 0x2; // Set to system
+
+
+ // -----------------------------------------------------------------
+
+ FAPI_INF("Executing proc_set_pore_bar...");
+ image_address = (uint64_t) i_image;
+ FAPI_DBG("Passed address 0x%16llX ", image_address);
+
+ // Get the Table Base Address from the image
+ l_ecmdRc = sbe_xip_get_scalar((void*) i_image,
+ "slw_branch_table",
+ &slw_branch_table_address);
+ if (l_ecmdRc)
+ {
+ FAPI_ERR("Get XIP of slw_branch_table failed. rc = %x\n", l_ecmdRc);
+ FAPI_SET_HWP_ERROR(rc, RC_PROCPM_POREBAR_IMAGE_BRANCH_VALUE_ERROR);
+ return rc;
+ }
+ FAPI_DBG("slw_branch_table_address: %16llX", slw_branch_table_address);
+
+ // Initialize the ecmdDataBuffer
+ l_ecmdRc |= data.clear();
+ l_ecmdRc |= data.setBitLength(64);
+ if(l_ecmdRc)
+ {
+ FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", l_ecmdRc);
+ rc.setEcmdError(l_ecmdRc);
+ return rc;
+ }
+
+
+ // Setup the the table base address register
+ //
+ // Table Base Address Register layout
+ // 16 Interface (0=PIB, 1=OCI)
+ // 17 Reserved
+ // 18:23 Chiplet ID (used only for PIB fetch; unused for OCI)-SLW unused
+ // 24:27 PIB ID (used only for PIB fetch; unused for OCI)-SLW unused
+ // 28:31 PORT ID (used only for PIB fetch; unused for OCI)-SLW unused
+ // 32:64 Table base address for jump table
+ //
+ // 1 2 3 3 6
+ // 6789012345678901 2-----3
+ // 1 OCI
+ // 0
+ // 000000 Chiplet ID
+ // 0000 PIB ID
+ // 0000 PORT ID
+ //
+ // For SLW images that will run on PORE-SLW, the PORT ID is set to C
+ //
+ //
+
+ // Set the table base address (32:63) with passed value
+ l_ecmdRc |= data.setDoubleWord( 0, slw_branch_table_address);
+ if(l_ecmdRc)
+ {
+ FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", l_ecmdRc);
+ rc.setEcmdError(l_ecmdRc);
+ return rc;
+ }
+ rc = fapiPutScom(i_target, PORE_SLW_TABLE_BASE_ADDR_0x00068008, data);
+ if (rc)
+ {
+ FAPI_ERR("Put SCOM error for Table Base Address");
+ return rc;
+ }
+ FAPI_INF("SLW PORE Table Base Address set to 0x%16llx", data.getDoubleWord(0));
+
+
+
+ // Setup the memory relocation register
+ //
+ // This is hardcoded as the SLW image build process has all images to be:
+ // 1) Relocatable and thus must have the region match bits set
+ // 2) Built for region 0x80000XXX
+ //
+ // MRR Layout
+ // 30:31: Memory Reloc Region - 2 MSbs of 32 bit address that
+ // defines the region match
+ // 32:51 Memory Relocation Base Address added to 0:19 of the OCI
+ // address
+ //
+ // Table Base Address Register layout
+ // 16 Interface (0=PIB, 1=OCI)
+ // 17 Reserved
+ // 18:23 Chiplet ID (used only for PIB fetch; unused for OCI)-SLW unused
+ // 24:27 PIB ID (used only for PIB fetch; unused for OCI)-SLW unused
+ // 28:31 PORT ID (used only for PIB fetch; unused for OCI)-SLW unused
+ // 32:64 Table base address for jump table
+ //
+ // 1 2 3 3 6
+ // 6789012345678901 2-----3
+ // 1 OCI
+ // 0
+ // 000000 Chiplet ID
+ // 0000 PIB ID
+ // 0000 PORT ID
+ //
+ // For SLW images that will run on PORE-SLW, the PORT ID is set to C in
+ // the image but this is unused by the hardware.
+
+ l_ecmdRc |= data.flushTo0();
+
+ // Set 30:31 to 10 to yield a region of 0x8XXXXXXX (eg unused OCI region)
+ l_ecmdRc |= data.setBit( 30, 1);
+
+ if(l_ecmdRc)
+ {
+ FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", l_ecmdRc);
+ rc.setEcmdError(l_ecmdRc);
+ return rc;
+ }
+
+ // SLW image has effective addresses in the form of 0x8XXXXXXX.
+ // The PORE memory relocation function adds the mem_reloc(32:52) to
+ // effective address 0:19 to form the real address where:
+ // effective address(0:1) defines the region: 00 = memory/L3, 11 = SRAM
+ // effective address(2:3) defines the PBA BAR to use (if memory/L3)
+
+ // Set the Memory Relocation Base based on the placement of the SLW image
+ if (i_mem_type == SLW_SRAM)
+ {
+ // Set the beginning of 512KB SRAM tank.
+
+ FAPI_DBG("SLW PORE Memory Relocation Register before SRAM 0x%16llx", data.getDoubleWord(0));
+
+ l_ecmdRc |= data.setOr(0x7FF80<<12, 32, 20);
+ if(l_ecmdRc)
+ {
+ FAPI_ERR("Error (0x%x) manipulating ecmdDataBufferBase", l_ecmdRc);
+ rc.setEcmdError(l_ecmdRc);
+ return rc;
+ }
+ }
+ else if (i_mem_type == SLW_MEMORY || i_mem_type == SLW_L3)
+ {
+ // The 00 (from the buffer flush) in 0:1 goes toward PBA (memory or L3)
+ // Set to use the PBA with BAR(0:3) encoded in bits 2:3 (eg shift of 30)
+ // 0x80000 + 0xA0000 => 20000 (upper overflow discarded)
+ // The 00 in 0:1 goes toward PBA; 2:3 for PBA BAR 2
+ FAPI_DBG("SLW PORE PBA BAR %x", pba_bar_slw);
+ FAPI_DBG("SLW PORE Memory Relocation Register before MEM 0x%16llx", data.getDoubleWord(0));
+
+ l_ecmdRc |= data.setOr(pba_bar_slw<<28, 32, 20);
+ if(l_ecmdRc)
+ {
+ FAPI_ERR("Error (0x%x) manipulating ecmdDataBufferBase", l_ecmdRc);
+ rc.setEcmdError(l_ecmdRc);
+ return rc;
+ }
+
+ FAPI_DBG("SLW PORE Memory Relocation Register after MEM 0x%16llx", data.getDoubleWord(0));
+
+ // Check that the bar address passed is 1MB aligned (eg bits 44:63 are zero)
+ //
+ region_masked_address = i_mem_bar & 0x00000000000FFFFF;
+ if (region_masked_address != 0 )
+ {
+ FAPI_ERR("SLW BAR address is not 1MB aligned: 0x%16llx", i_mem_bar );
+ FAPI_SET_HWP_ERROR(rc, RC_PROCPM_POREBAR_PBABAR_ERROR);
+ return rc;
+ }
+
+
+ // The PBA Mask indicates which bits from 23:43 (1MB grandularity) are
+ // enabled to be passed from the OCI addresses. Inverting this mask
+ // indicates which address bits are going to come from the PBA BAR value.
+ // The image address (the starting address) must match these post mask bits
+ // to be resident in the range.
+ //
+ // Starting bit number: 64 bit Big Endian
+ // 12223344
+ // 60482604
+ // region_inverted_mask = i_mem_mask ^ BAR_MASK_LIMIT; // XOR
+
+
+ // Check that the image address passed is within the memory region that
+ // is also passed.
+ //
+ // The PBA Mask indicates which bits from 23:43 (1MB grandularity) are
+ // enabled to be passed from the OCI addresses. Inverting this mask
+ // indicates which address bits are going to come from the PBA BAR value.
+ // The image address (the starting address) must match these post mask bits
+ // to be resident in the range.
+ //
+ // Starting bit number: 64 bit Big Endian
+ // 12223344
+ // 60482604
+ // region_inverted_mask = i_mem_mask ^ BAR_MASK_LIMIT; // XOR
+
+ // Set bits 14:22 as these are unconditional address bits
+ //region_inverted_mask = region_inverted_mask | BAR_ADDR_UNMASKED;
+ //computed_image_address = region_inverted_mask && image_address;
+ // Need to AND the address
+ //if (computed_image_address != i_mem_bar )
+ //{
+ // FAPI_ERR("SLW image address check failure. ");
+ // FAPI_SET_HWP_ERROR(rc, RC_PROCPM_POREBAR_IMAGE_ADDR_ERROR);
+ // return rc;
+ //}
+
+
+ // Additionally, the size of the image must not extend beyond the above
+ // masked range either.
+
+ // Get the image size from the image itself
+ l_ecmdRc = sbe_xip_get_scalar((void*) i_image,
+ "image_size",
+ &image_size);
+
+ if (l_ecmdRc)
+ {
+ FAPI_ERR("Get of XIP Image size failed");
+ FAPI_SET_HWP_ERROR(rc, RC_PROCPM_POREBAR_IMAGE_SIZE_ERROR);
+ return rc;
+ }
+
+ FAPI_DBG("SLW image size: 0x%08llX", image_size );
+ // computed_last_image_address = image_address + image_size;
+ //
+ // if (computed_last_image_address > region_end_address)
+ // {
+ // FAPI_ERR("SLW image placement error.");
+ // FAPI_SET_HWP_ERROR(rc, RC_PROCPM_POREBAR_IMAGE_PLACEMENT_ERROR);
+ // return rc;
+ // }
+
+ }
+ else
+ {
+ FAPI_ERR("Invalid image location passed %x ", i_mem_type);
+ FAPI_SET_HWP_ERROR(rc, RC_PROCPM_POREBAR_LOC_ERROR);
+ return rc;
+ }
+
+ FAPI_INF("SLW PORE Memory Relocation Register set to 0x%16llx", data.getDoubleWord(0));
+ rc = fapiPutScom(i_target, PORE_SLW_MEMORY_RELOC_0x00068016, data);
+ if (rc)
+ {
+ FAPI_ERR("Put SCOM error for Memory Relocation Address");
+ return rc;
+ }
+
+
+
+
+
+
+ FAPI_DBG("Calling pba_bar_config to BAR %x Addr: 0x%16llX Mask: 0x%16llX",
+ pba_bar, i_mem_bar, i_mem_mask);
+
+ // Set the PBA BAR for the SLW region
+ FAPI_EXEC_HWP(rc, proc_pba_bar_config, i_target,
+ pba_bar,
+ i_mem_bar,
+ i_mem_mask,
+ slw_pba_cmd_scope);
+ if(rc) { return rc; }
+
+ // Set the PBA Slave to use the above BAR
+ // \todo Does not yet comprehend the 24x7 setting to allow writing!!
+ //
+ // enable = 1; // Enable the slave
+ // mid_match_value=0x4; // PORE-SLW engine
+ // mid_care_mask=0x7; // Only the PORE-SLW
+ // write_ttype=0; // DMA - though NA
+ // read_ttype=0; // CL_RD_NC
+ // read_prefetch_ctl=0; // Auto Early
+ // buf_invalidate_ctl=0; // Disabled
+ // buf_alloc_w=0; // SLW does not write. 24x7 will
+ // buf_alloc_a=0; // SLW uses Buf A
+ // buf_alloc_b=0; // SLW does not use buffer B
+ // buf_alloc_c=0; // SLW does not use buffer C
+ // dis_write_gather=0; // SLW does not write. \todo 24x7
+ // wr_gather_timeout=0; // SLW does not write \todo 24x7
+ // write_tsize=0; // SLW does not write \todo 24x7
+ // extaddr=0; // Bits 23:36. NA for SLW
+ //
+
+ // Clear the data buffer (for cleanliness)
+ l_ecmdRc |= data.flushTo0();
+
+
+ // set the PBASLVCTL reg
+ l_ecmdRc |= data.setBit(0); // Enable the slave
+ l_ecmdRc |= data.setBit(1); // PORE-SLW engine - 0b100
+ l_ecmdRc |= data.setBit(5,3); // Care mask-only PORE-SLW
+
+ if(l_ecmdRc)
+ {
+ FAPI_ERR("Error (0x%x) manipulating ecmdDataBufferBase for PBASLVCTL", l_ecmdRc);
+ rc.setEcmdError(l_ecmdRc);
+ return rc;
+ }
+
+ FAPI_DBG(" PBA_SLVCTL%x: 0x%16llx", pba_slave, data.getDoubleWord(0));
+ rc = fapiPutScom(i_target, PBA_SLVCTLs[pba_slave], data);
+ if (rc)
+ {
+ FAPI_ERR("Put SCOM error for PBA Slave Control");
+ return rc;
+ }
+
+ return rc;
+}
+
+
+} //end extern C
diff --git a/src/usr/hwpf/hwp/build_winkle_images/proc_set_pore_bar/proc_set_pore_bar.H b/src/usr/hwpf/hwp/build_winkle_images/proc_set_pore_bar/proc_set_pore_bar.H
new file mode 100644
index 000000000..3083ff35c
--- /dev/null
+++ b/src/usr/hwpf/hwp/build_winkle_images/proc_set_pore_bar/proc_set_pore_bar.H
@@ -0,0 +1,123 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/hwpf/hwp/build_winkle_images/proc_set_pore_bar/proc_set_pore_bar.H $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
+// $Id: proc_set_pore_bar.H,v 1.3 2012/07/20 21:14:11 stillgs Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/proc_set_pore_bar.H,v $
+//------------------------------------------------------------------------------
+// *|
+// *! (C) Copyright International Business Machines Corp. 2011
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+// *|
+// *! TITLE : proc_set_pore_bar.H
+// *! DESCRIPTION : Establish the BAR setup for the SLW image in the PBA as
+// *! well as setting up the SLW engine with table base address
+// *! and memory relocation regs in the SLW
+// *!
+// *! OWNER NAME : Greg Still Email: stillgs@us.ibm.com
+// *! BACKUP NAME : Jim Yacynych Email: jimyac@us.ibm.com
+// *!
+//------------------------------------------------------------------------------
+
+#ifndef _PROC_SET_PORE_BAR_H_
+#define _PROC_SET_PORE_BAR_H_
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+
+
+// function pointer typedef definition for HWP call support
+typedef fapi::ReturnCode (*proc_set_pore_bar_FP_t) (const fapi::Target&,
+ void*,
+ uint64_t,
+ uint64_t,
+ uint32_t
+ );
+
+extern "C" {
+
+
+//------------------------------------------------------------------------------
+// Constant definitions
+//------------------------------------------------------------------------------
+
+enum PORE_SLW_LOC {
+ SLW_MEMORY = 0x0,
+ SLW_L3 = 0x1,
+ SLW_SRAM = 0x2
+ };
+
+// The value here will yield the appropriate nibble for accessing the PowerBus
+// Regions (eg 0:1 = 00) when added to 0x8 (the SLW image effective address upper
+// nibble) - 4 bit math only.
+enum PORE_SLW_PBA_BAR {
+ PBA_SLW_BAR0 = 0x8, // 0x8 + 0x8 = 0x0
+ PBA_SLW_BAR1 = 0x9, // 0x8 + 0x9 = 0x1
+ PBA_SLW_BAR2 = 0xA, // 0x8 + 0xA = 0x2
+ PBA_SLW_BAR3 = 0xB // 0x8 + 0xB = 0x3
+ };
+
+enum PORE_PBA_BAR {
+ PBA_BAR0 = 0x0,
+ PBA_BAR1 = 0x1,
+ PBA_BAR2 = 0x2,
+ PBA_BAR3 = 0x3
+ };
+
+enum PORE__BA_SLAVE {
+ PBA_SLAVE0 = 0x0,
+ PBA_SLAVE1 = 0x1,
+ PBA_SLAVE2 = 0x2,
+ PBA_SLAVE3 = 0x3
+ };
+
+//------------------------------------------------------------------------------
+// Parameter structure definitions
+//------------------------------------------------------------------------------
+
+
+
+//------------------------------------------------------------------------------
+// Function prototype
+//------------------------------------------------------------------------------
+/// \param[in] i_target Procesor Chip target
+/// \param[in] i_image Platform memory pointer where image is
+/// located
+/// \param[in] i_mem_bar Base address of the region where image is located
+/// \param[in] i_mem_mask Mask that defines which address bits of the
+/// BAR apply such to define the region size
+/// \param[in] i_mem_type Defines where the SLW image was loaded. See
+/// proc_set_pore_bar.H enum for valid values.
+
+fapi::ReturnCode
+proc_set_pore_bar( const fapi::Target& i_target,
+ void *i_image,
+ uint64_t i_mem_bar,
+ uint64_t i_mem_mask,
+ uint32_t i_mem_type);
+
+
+} // extern "C"
+
+#endif // _PROC_SET_PORE_BAR_H_
diff --git a/src/usr/hwpf/hwp/build_winkle_images/proc_set_pore_bar/proc_set_pore_bar_errors.xml b/src/usr/hwpf/hwp/build_winkle_images/proc_set_pore_bar/proc_set_pore_bar_errors.xml
new file mode 100644
index 000000000..d053b9fcb
--- /dev/null
+++ b/src/usr/hwpf/hwp/build_winkle_images/proc_set_pore_bar/proc_set_pore_bar_errors.xml
@@ -0,0 +1,56 @@
+<!-- IBM_PROLOG_BEGIN_TAG
+ This is an automatically generated prolog.
+
+ $Source: src/usr/hwpf/hwp/build_winkle_images/proc_set_pore_bar/proc_set_pore_bar_errors.xml $
+
+ IBM CONFIDENTIAL
+
+ COPYRIGHT International Business Machines Corp. 2012
+
+ p1
+
+ Object Code Only (OCO) source materials
+ Licensed Internal Code Source Materials
+ IBM HostBoot Licensed Internal Code
+
+ The source code for this program is not published or other-
+ wise divested of its trade secrets, irrespective of what has
+ been deposited with the U.S. Copyright Office.
+
+ Origin: 30
+
+ IBM_PROLOG_END_TAG -->
+<!-- Error definitions for proc_set_pore_bar procedure -->
+<hwpErrors>
+ <!-- *********************************************************************** -->
+ <hwpError>
+ <rc>RC_PROCPM_POREBAR_IMAGE_BRANCH_VALUE_ERROR</rc>
+ <description>XIP access of branch table failed in proc_set_pore_bar</description>
+ </hwpError>
+ <!-- *********************************************************************** -->
+ <hwpError>
+ <rc>RC_PROCPM_POREBAR_LOC_ERROR</rc>
+ <description>Invalid image location passed to proc_set_pore_bar</description>
+ </hwpError>
+ <!-- *********************************************************************** -->
+ <hwpError>
+ <rc>RC_PROCPM_POREBAR_PBABAR_ERROR</rc>
+ <description>PBA BAR image location passed to proc_set_pore_bar</description>
+ </hwpError>
+ <!-- *********************************************************************** -->
+ <hwpError>
+ <rc>RC_PROCPM_POREBAR_IMAGE_SIZE_ERROR</rc>
+ <description>XIP access to size value failed in proc_set_pore_bar</description>
+ <description>Image address plus image size overflows PBA region in proc_set_pore_bar</description>
+ </hwpError>
+ <!-- *********************************************************************** -->
+ <hwpError>
+ <rc>RC_PROCPM_POREBAR_IMAGE_PLACEMENT_ERROR</rc>
+ <description>Image address plus image size overflows PBA region in proc_set_pore_bar</description>
+ </hwpError>
+ <!-- *********************************************************************** -->
+ <hwpError>
+ <rc>RC_PROCPM_POREBAR_IMAGE_ADDR_ERROR</rc>
+ <description>Image address not in PBA BAR region in proc_set_pore_bar</description>
+ </hwpError>
+</hwpErrors>
diff --git a/src/usr/hwpf/hwp/build_winkle_images/proc_set_pore_bar/sbe_xip_image.h b/src/usr/hwpf/hwp/build_winkle_images/proc_set_pore_bar/sbe_xip_image.h
new file mode 100644
index 000000000..4109659ea
--- /dev/null
+++ b/src/usr/hwpf/hwp/build_winkle_images/proc_set_pore_bar/sbe_xip_image.h
@@ -0,0 +1,1749 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/hwpf/hwp/build_winkle_images/proc_set_pore_bar/sbe_xip_image.h $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
+#ifndef __SBE_XIP_IMAGE_H
+#define __SBE_XIP_IMAGE_H
+
+// $Id: sbe_xip_image.h,v 1.17 2012/06/12 13:30:28 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/sbe/sbe_xip_image.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2011
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+// *! OWNER NAME: Bishop Brock Email: bcbrock@us.ibm.com
+//------------------------------------------------------------------------------
+
+/// \file sbe_xip_image.h
+/// \brief Everything related to creating and manipulating SBE-XIP binary
+/// images.
+
+#include "fapi_sbe_common.H"
+
+/// Current version (fields, layout, sections) of the SBE_XIP header
+///
+/// If any changes are made to this file or to sbe_xip_header.H, please update
+/// the header version and follow-up on all of the error messages.
+
+#define SBE_XIP_HEADER_VERSION 8
+
+/// \defgroup sbe_xip_magic_numbers SBE-XIP magic numbers
+///
+/// An SBE-XIP magic number is a 64-bit constant. The 4 high-order bytes
+/// contain the ASCII characters "XIP " and identify the image as an SBE-XIP
+/// image, while the 4 low-order bytes identify the type of the image.
+///
+/// @{
+
+#define SBE_XIP_MAGIC 0x58495020 // "XIP "
+#define SBE_BASE_MAGIC ULL(0x5849502042415345) // "XIP BASE"
+#define SBE_SEEPROM_MAGIC ULL(0x584950205345504d) // "XIP SEPM"
+#define SBE_CENTAUR_MAGIC ULL(0x58495020434e5452) // "XIP CNTR"
+
+/// @}
+
+
+/// \defgroup sbe_xip_sections SBE-XIP Image Section Indexes
+///
+/// These constants define the order that the SbeXipSection structures appear
+/// in the header, which is not necessarily the order the sections appear in
+/// the binary image. Given that SBE-XIP image contents are tightly
+/// controlled, we use this simple indexing scheme for the allowed sections
+/// rather than a more general approach, e.g., allowing arbitrary sections
+/// identified by their names.
+///
+/// @{
+
+// -*- DO NOT REORDER OR EDIT THIS SET OF CONSTANTS WITHOUT ALSO EDITING -*-
+// -*- THE ASSEMBLER LAYOUT IN sbe_xip_header.S. -*-
+
+#define SBE_XIP_SECTION_HEADER 0
+#define SBE_XIP_SECTION_FIXED 1
+#define SBE_XIP_SECTION_FIXED_TOC 2
+#define SBE_XIP_SECTION_IPL_TEXT 3
+#define SBE_XIP_SECTION_IPL_DATA 4
+#define SBE_XIP_SECTION_TEXT 5
+#define SBE_XIP_SECTION_DATA 6
+#define SBE_XIP_SECTION_TOC 7
+#define SBE_XIP_SECTION_STRINGS 8
+#define SBE_XIP_SECTION_HALT 9
+#define SBE_XIP_SECTION_PIBMEM0 10
+#define SBE_XIP_SECTION_PIBMEM1 11
+#define SBE_XIP_SECTION_RINGS 12
+#define SBE_XIP_SECTION_SLW 13
+#define SBE_XIP_SECTION_RESERVED_1 14
+#define SBE_XIP_SECTION_RESERVED_0 15
+
+#define SBE_XIP_SECTIONS 16
+
+/// @}
+
+#ifndef __ASSEMBLER__
+
+/// Applications can expand this macro to create an array of section names.
+#define SBE_XIP_SECTION_NAMES(var) \
+ const char* var[] = { \
+ ".header", \
+ ".fixed", \
+ ".fixed_toc", \
+ ".ipl_text", \
+ ".ipl_data", \
+ ".text", \
+ ".data", \
+ ".toc", \
+ ".strings", \
+ ".halt", \
+ ".pibmem0", \
+ ".pibmem1", \
+ ".rings", \
+ ".slw", \
+ ".reserved_1", \
+ ".reserved_0" \
+ }
+
+/// Applications can use this macro to safely index the array of section
+/// names.
+#define SBE_XIP_SECTION_NAME(var, n) \
+ ((((n) < 0) || ((n) > (int)(sizeof(var) / sizeof(char*)))) ? \
+ "Bug : Invalid SBE-XIP section name" : var[n])
+
+
+#endif /* __ASSEMBLER__ */
+
+
+/// Maximum section alignment for SBE-XIP sections
+#define SBE_XIP_MAX_SECTION_ALIGNMENT 128
+
+/// defgroup sbe_xip_toc_types SBE-XIP Table of Contents data types
+///
+/// These are the data types stored in the \a iv_type field of the SbeXipToc
+/// objects. These must be defined as manifest constants because they are
+/// required to be recognized as manifest constants in C (as opposed to C++)
+/// code.
+///
+/// NB: The 0x0 code is purposefully left undefined to catch bugs.
+///
+/// @{
+
+/// Data is a single unsigned byte
+#define SBE_XIP_UINT8 0x01
+
+/// Data is a 32-bit unsigned integer
+#define SBE_XIP_UINT32 0x02
+
+/// Data is a 64-bit unsigned integer
+#define SBE_XIP_UINT64 0x03
+
+/// Data is a 0-byte terminated ASCII string
+#define SBE_XIP_STRING 0x04
+
+/// Data is an address
+#define SBE_XIP_ADDRESS 0x05
+
+/// The maximum type number
+#define SBE_XIP_MAX_TYPE_INDEX 0x05
+
+/// Applications can expand this macro to get access to string forms of the
+/// SBE-XIP data types if desired.
+#define SBE_XIP_TYPE_STRINGS(var) \
+ const char* var[] = { \
+ "Illegal 0 Code", \
+ "SBE_XIP_UINT8", \
+ "SBE_XIP_UINT32", \
+ "SBE_XIP_UINT64", \
+ "SBE_XIP_STRING", \
+ "SBE_XIP_ADDRESS", \
+ }
+
+/// Applications can expand this macro to get access to abbreviated string
+/// forms of the SBE-XIP data types if desired.
+#define SBE_XIP_TYPE_ABBREVS(var) \
+ const char* var[] = { \
+ "Illegal 0 Code", \
+ "u8 ", \
+ "u32", \
+ "u64", \
+ "str", \
+ "adr", \
+ }
+
+/// Applications can use this macro to safely index either array of SBE-XIP
+/// type strings.
+#define SBE_XIP_TYPE_STRING(var, n) \
+ (((n) > (sizeof(var) / sizeof(char*))) ? \
+ "Invalid SBE-XIP type specification" : var[n])
+
+/// @}
+
+
+/// Final alignment constraint for SBE-XIP images.
+///
+/// PORE images are required to be multiples of 8 bytes in length, to
+/// gaurantee that the PoreVe will be able to complete any 8-byte load/store.
+#define SBE_XIP_FINAL_ALIGNMENT 8
+
+
+////////////////////////////////////////////////////////////////////////////
+// C Definitions
+////////////////////////////////////////////////////////////////////////////
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#if 0
+} /* So __cplusplus doesn't mess w/auto-indent */
+#endif
+
+/// SBE-XIP Section information
+///
+/// This structure defines the data layout of section table entries in the
+/// SBE-XIP image header.
+
+// -*- DO NOT REORDER OR EDIT THIS STRUCTURE DEFINITION WITHOUT ALSO -*-
+// -*- EDITING THE ASSEMBLER LAYOUT IN sbe_xip_header.H -*-
+
+typedef struct {
+
+ /// The offset (in bytes) of the section from the beginning of the image
+ ///
+ /// In normalized images the section offset will always be 0 if the
+ /// section size is also 0.
+ uint32_t iv_offset;
+
+ /// The size of the section in bytes, exclusive of alignment padding
+ ///
+ /// This is the size of the program-significant data in the section,
+ /// exclusive of any alignment padding or reserved or extra space. The
+ /// alignment padding (reserved space) is not represented explicitly, but
+ /// is only implied by the offset of any subsequent non-empty section, or
+ /// in the case of the final section in the image, the image size.
+ ///
+ /// Regardless of the \a iv_offset, if the \a iv_size of a section is 0 it
+ /// should be considered "not present" in the image. In normalized images
+ /// the section offset will always be 0 if the section size is also 0.
+ uint32_t iv_size;
+
+ /// The required initial alignment for the section offset
+ ///
+ /// The PORE and the applications using SBE-XIP images have strict
+ /// alignment/padding requirements. The PORE does not handle any type of
+ /// unaligned instruction or data fetches. Some sections and subsections
+ /// must also be POWER cache-line aligned. The \a iv_alignment applies to
+ /// the first byte of the section. PORE images are also required to be
+ /// multiples of 8 bytes in length, to gaurantee that the PoreVe will be
+ /// able to complete any 8-byte load/store. These constraints are checked
+ /// by sbe_xip_validate() and enforced by sbe_xip_append(). The alignment
+ /// constraints may force a section to be padded, which may create "holes"
+ /// in the image as explained in the comments for the \a iv_size field.
+ ///
+ /// Note that alignment constraints are always checked relative to the
+ /// first byte of the image for in-memory images, not relative to the host
+ /// address. Alignment specifications are required to be a power-of-2.
+ uint8_t iv_alignment;
+
+ /// Reserved structure alignment padding; Pad to 12 bytes
+ uint8_t iv_reserved8[3];
+
+} SbeXipSection;
+
+/// The SbeXipSection structure is created by assembler code and is expected
+/// to have the same size in C code. This constraint is checked in
+/// sbe_xip_validate().
+#define SIZE_OF_SBE_XIP_SECTION 12
+
+
+/// SBE-XIP binary image header
+///
+/// This header occupies the initial bytes of an SBE-XIP binary image.
+/// The header contents are documented here, however the structure is actually
+/// defined in the file sbe_xip_header.S, and these two definitions must be
+/// kept consistent.
+///
+/// The header is a fixed-format representation of the most critical
+/// information about the image. The large majority of information about the
+/// image and its contents are available through the searchable table of
+/// contents. PORE code itself normally accesses the data directly through
+/// global symbols.
+///
+/// The header only contains information 1) required by OTPROM code (e.g., the
+/// entry point); 2) required by search and updating APIs (e.g., the
+/// locations and sizes of all of the sections.); a few pieces of critical
+/// meta-data (e.g., information about the image build process).
+///
+/// Any entries that are accessed by PORE code are required to be 64 bits, and
+/// will appear at the beginning of the header.
+///
+/// The header also contains bytewise offsets and sizes of all of the sections
+/// that are assembled to complete the image. The offsets are relative to the
+/// start of the image (where the header is loaded). The sizes include any
+/// padding inserted by the link editor to guarantee section alignment.
+///
+/// Every field of the header is also accesssible through the searchable table
+/// of contents as documented in sbe_xip_header.S.
+
+// -*- DO NOT REORDER OR EDIT THIS STRUCTURE DEFINITION WITHOUT ALSO -*-
+// -*- EDITING THE ASSEMBLER LAYOUT IN sbe_xip_header.S, AND WITHOUT -*-
+// -*- UPDATING THE sbe_xip_translate_header() API IN sbe_xip_image.c. -*-
+
+typedef struct {
+
+ //////////////////////////////////////////////////////////////////////
+ // Identification - 8-byte aligned; 8 entries
+ //////////////////////////////////////////////////////////////////////
+
+ /// Contains SBE_XIP_MAGIC to identify an SBE-XIP image
+ uint64_t iv_magic;
+
+ /// The offset of the SBE-XIP entry point from the start of the image
+ uint64_t iv_entryOffset;
+
+ /// The base address used to link the image, as a full relocatable PORE
+ /// address
+ uint64_t iv_linkAddress;
+
+ /// Reserved for future expansion
+ uint64_t iv_reserved64[5];
+
+ //////////////////////////////////////////////////////////////////////
+ // Section Table - 4-byte aligned; 16 entries
+ //////////////////////////////////////////////////////////////////////
+
+ SbeXipSection iv_section[SBE_XIP_SECTIONS];
+
+ //////////////////////////////////////////////////////////////////////
+ // Other information - 4-byte aligned; 8 entries
+ //////////////////////////////////////////////////////////////////////
+
+ /// The size of the image (including padding) in bytes
+ uint32_t iv_imageSize;
+
+ /// Build date generated by `date +%Y%m%d`, e.g., 20110630
+ uint32_t iv_buildDate;
+
+ /// Build time generated by `date +%H%M`, e.g., 0756
+ uint32_t iv_buildTime;
+
+ /// Reserved for future expansion
+ uint32_t iv_reserved32[5];
+
+ //////////////////////////////////////////////////////////////////////
+ // Other Information - 1-byte aligned; 8 entries
+ //////////////////////////////////////////////////////////////////////
+
+ /// Header format version number
+ uint8_t iv_headerVersion;
+
+ /// Indicates whether the image has been normalized (0/1)
+ uint8_t iv_normalized;
+
+ /// Indicates whether the TOC has been sorted to speed searching (0/1)
+ uint8_t iv_tocSorted;
+
+ /// Reserved for future expansion
+ uint8_t iv_reserved8[5];
+
+ //////////////////////////////////////////////////////////////////////
+ // Strings; 64 characters allocated
+ //////////////////////////////////////////////////////////////////////
+
+ /// Build user, generated by `id -un`
+ char iv_buildUser[16];
+
+ /// Build host, generated by `hostname`
+ char iv_buildHost[24];
+
+ /// Reserved for future expansion
+ char iv_reservedChar[24];
+
+} SbeXipHeader;
+
+
+/// A C-structure form of the SBE-XIP Table of Contents (TOC) entries
+///
+/// The .toc section consists entirely of an array of these structures.
+/// TOC entries are never accessed by PORE code.
+///
+/// These structures store indexing information for global data required to be
+/// manipulated by external tools. The actual data is usually allocated in a
+/// data section and manipulated by the SBE code using global or local symbol
+/// names. Each TOC entry contains a pointer to a keyword string naming the
+/// data, the address of the data (or the data itself), the data type,
+/// meta-information about the data, and for vectors the vector size.
+
+// -*- DO NOT REORDER OR EDIT THIS STRUCTURE DEFINITION WITHOUT ALSO -*-
+// -*- EDITING THE ASSEMBLER MACROS (BELOW) THAT CREATE THE TABLE OF -*-
+// -*- CONTENTS ENTRIES. -*-
+
+typedef struct {
+
+ /// A pointer to a 0-byte terminated ASCII string identifying the data.
+ ///
+ /// When allocated by the .xip_toc macro this is a pointer to the string
+ /// form of the symbol name for the global or local symbol associated with
+ /// the data which is allocated in the .strings section. This pointer is
+ /// not aligned.
+ ///
+ /// When the image is normalized this pointer is replaced by the offset of
+ /// the string in the .strings section.
+ uint32_t iv_id;
+
+ /// A 32-bit pointer locating the data
+ ///
+ /// This field is initially populated by the link editor. For scalar,
+ /// vector and string types this is the final relocated address of the
+ /// first byte of the data. For address types, this is the relocated
+ /// address. When the image is normalized, these addresses are converted
+ /// into the equivalent offsets from the beginning of the section holding
+ /// the data.
+ uint32_t iv_data;
+
+ /// The type of the data; See \ref sbe_xip_toc_types.
+ uint8_t iv_type;
+
+ /// The section containing the data; See \ref sbe_xip_sections.
+ uint8_t iv_section;
+
+ /// The number of elements for vector types, otherwise 1 for scalar types
+ /// and addresses.
+ ///
+ /// Vectors are naturally limited in size, e.g. to the number of cores,
+ /// chips in a node, DD-levels etc. If \a iv_elements is 0 then no bounds
+ /// checking is done on get/set accesses of the data.
+ uint8_t iv_elements;
+
+ /// Structure alignment padding; Pad to 12 bytes
+ uint8_t iv_pad;
+
+} SbeXipToc;
+
+/// The SbeXipToc structure is created by assembler code and is expected
+/// to have the same size in C code. This constraint is checked in
+/// sbe_xip_validate().
+#define SIZE_OF_SBE_XIP_TOC 12
+
+
+/// A C-structure form of hashed SBE-XIP Table of Contents (TOC) entries
+///
+/// This structure was introduced in order to allow a small TOC for the .fixed
+/// section to support minimum-sized SEEPROM images in which the global TOC
+/// and all strings have been stripped out. In this structure the index
+/// string has been replaced by a 32-bit hash, and there is no longer a record
+/// of the original data name other then the hash. The section of the data is
+/// assumed to be .fixed, with a maximum 16-bit offset.
+///
+/// These structures are created when entries are made in the .fixed section.
+/// They are created empty, then filled in during image normalization.
+///
+/// This structure allows the sbe_xip_get*() and sbe_xip_set*() APIs to work
+/// even on highly-stripped SEEPROM images.
+
+typedef struct {
+
+ /// A 32-bit hash (FNV-1a) of the Id string.
+ uint32_t iv_hash;
+
+ /// The offset in bytes from the start of the (implied) section of the data
+ uint16_t iv_offset;
+
+ /// The type of the data; See \ref sbe_xip_toc_types.
+ uint8_t iv_type;
+
+ /// The number of elements for vector types, otherwise 1 for scalar types
+ /// and addresses.
+ ///
+ /// Vectors are naturally limited in size, e.g. to the number of cores,
+ /// chips in a node, DD-levels etc. If \a iv_elements is 0 then no bounds
+ /// checking is done on get/set accesses of the data.
+ uint8_t iv_elements;
+
+} SbeXipHashedToc;
+
+/// The SbeXipHashedToc structure is created by assembler code and is expected
+/// to have the same size in C code. This constraint is checked in
+/// sbe_xip_validate().
+#define SIZE_OF_SBE_XIP_HASHED_TOC 8
+
+
+/// A decoded TOC entry for use by applications
+///
+/// This structure is a decoded form of a normalized TOC entry, filled in by
+/// the sbe_xip_decode_toc() and sbe_xip_find() APIs. This structure is
+/// always returned with data elements in host-endian format.
+///
+/// In the event that the TOC has been removed from the image, this structure
+/// will also be returned by sbe_xip_find() with information populated from
+/// the .fixed_toc section if possible. In this case the field \a iv_partial
+/// will be set and only the fields \a iv_address, \a iv_imageData, \a iv_type
+/// and \a iv_elements will be populated (all other fields will be set to 0).
+///
+/// \note Only special-purpose applications will ever need to use this
+/// structure given that the higher-level APIs sbe_xip_get_*() and
+/// sbe_xip_set_*() are provided and should be used if possible, especially
+/// given that the information may be truncated as described above.
+
+typedef struct {
+
+ /// A pointer to the associated TOC entry as it exists in the image
+ ///
+ /// If \a iv_partial is set this field is returned as 0.
+ SbeXipToc* iv_toc;
+
+ /// The full relocatable PORE address
+ ///
+ /// All relocatable addresses are computed from the \a iv_linkAddress
+ /// stored in the header. For scalar and string data, this is the
+ /// relocatable address of the data. For address-only entries, this is
+ /// the indexed address itself.
+ uint64_t iv_address;
+
+ /// A host pointer to the first byte of text or data within the image
+ ///
+ /// For scalar or string types this is a host pointer to the first byte of
+ /// the data. For code pointers (addresses) this is host pointer to the
+ /// first byte of code. Note that any use of this field requires the
+ /// caller to handle conversion of the data to host endian-ness if
+ /// required. Only 8-bit and string data can be used directly on all
+ /// hosts.
+ void* iv_imageData;
+
+ /// The item name
+ ///
+ /// This is a pointer in host memory to a string that names the TOC entry
+ /// requested. This field is set to a pointer to the ID string of the TOC
+ /// entry inside the image. If \a iv_partial is set this field is returned
+ /// as 0.
+ char* iv_id;
+
+ /// The data type, one of the SBE_XIP_* constants
+ uint8_t iv_type;
+
+ /// The number of elements in a vector
+ ///
+ /// This field is set from the TOC entry when the TOC entry is
+ /// decoded. This value is stored as 1 for scalar declarations, and may be
+ /// set to 0 for vectors with large or undeclared sizes. Otherwise it is
+ /// used to bounds check indexed accesses.
+ uint8_t iv_elements;
+
+ /// Is this record only partially populated?
+ ///
+ /// This field is set to 0 normally, and only set to 1 if a lookup is made
+ /// in an image that only has the fixed TOC and the requested Id hashes to
+ /// the fixed TOC.
+ uint8_t iv_partial;
+
+} SbeXipItem;
+
+
+/// Prototype entry in the .halt section
+///
+/// The .halt section is generated by the 'reqhalt' macro. This structure
+/// associates the address of each halt with the string form of the FAPI
+/// return code associated with the halt. The string form is used because the
+/// FAPI error return code is not constant. The .halt section is 4-byte
+/// aligned, and each address/string entry is always padded to a multiple of 4
+/// bytes.
+///
+/// In the .halt section the \a iv_string may be any length, thus the size of
+/// each actual record is variable (although guaranteed to always be a
+/// multiple of 4 bytes). Although the C compiler might natuarlly align
+/// instances of this structure on a 64-bit boundary, the APIs that allow
+/// access to the .halt section assume that the underlying machine can do
+/// non-aligned loads from a pointer to this structure.
+
+typedef struct {
+
+ /// The 64-bit relocatable address of the halt
+ ///
+ /// This is the address found in the PC (Status Register bits 16:63) when
+ /// the PORE halts. The full 64-bit form is used rather than the simple
+ /// 32-bit offset to support merging SEEPROM and PIBMEM .halt sections in
+ /// the SEEPROM IPL images.
+ uint64_t iv_address;
+
+ /// A C-prototype for a variable-length 0-terminated ASCII string
+ ///
+ /// This is a prototype only to simplify C programming. The actual string
+ /// may be any length.
+ char iv_string[4];
+
+} SbeXipHalt;
+
+
+/// Validate an SBE-XIP image
+///
+/// \param[in] i_image A pointer to an SBE-XIP image in host memory.
+///
+/// \param[in] i_size The putative size of the image
+///
+/// This API should be called first by all applications that manipulate
+/// SBE-XIP images in host memory. The magic number is validated, and
+/// the image is checked for consistency of the section table and table of
+/// contents. The \a iv_imageSize field of the header must also match the
+/// provided \a i_size parameter. Validation does not modify the image.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_validate(void* i_image, const uint32_t i_size);
+
+
+/// Normalize the SBE-XIP image
+///
+/// \param[in] io_image A pointer to an SBE-XIP image in host memory. The
+/// image is assumed to be consistent with the information contained in the
+/// header regarding the presence of and sizes of all sections.
+///
+/// SBE-XIP images must be normalized before any other APIs are allowed to
+/// operate on the image. Since normalization modifies the image, an explicit
+/// call to normalize the image is required. Briefly, normalization modifies
+/// the TOC entries created by the final link to simplify search, updates,
+/// modification and relocation of the image. Normalization is explained in
+/// the written documentation of the SBE-XIP binary format. Normalization does
+/// not modify the size of the image.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_normalize(void* io_image);
+
+
+/// Return the size of an SBE-XIP image from the image header
+///
+/// \param[in] i_image A pointer to an SBE-XIP image in host memory. The
+/// image is assumed to be consistent with the information contained in the
+/// header regarding the presence of and sizes of all sections.
+///
+/// \param[out] o_size A pointer to a variable returned as the size of the
+/// image in bytes, as recorded in the image header.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_image_size(void* i_image, uint32_t* o_size);
+
+
+/// Locate a section table entry and translate into host format
+///
+/// \param[in] i_image A pointer to an SBE-XIP image in host memory.
+///
+/// \param[in] i_sectionId Identifies the section to be queried. See \ref
+/// sbe_xip_sections.
+///
+/// \param[out] o_hostSection Updated to contain the section table entry
+/// translated to host byte order.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_get_section(const void* i_image,
+ const int i_sectionId,
+ SbeXipSection* o_hostSection);
+
+
+/// Endian translation of an SbeXipHeader object
+///
+/// \param[out] o_hostHeader The destination object.
+///
+/// \param[in] i_imageHeader The source object.
+///
+/// Translation of a SbeXipHeader includes translation of all data members
+/// including traslation of the embedded section table. This translation
+/// works even if \a o_src == \a o_dest, i.e., in the destructive case.
+void
+sbe_xip_translate_header(SbeXipHeader* o_hostHeader,
+ const SbeXipHeader* i_imageHeader);
+
+
+/// Get scalar data from an SBE-XIP image
+///
+/// \param[in] i_image A pointer to an SBE-XIP image in host memory. The
+/// image is assumed to be consistent with the information contained in the
+/// header regarding the presence of and sizes of all sections. The image is
+/// also required to have been normalized.
+///
+/// \param[in] i_id A pointer to a 0-terminated ASCII string naming the item
+/// requested.
+///
+/// \param[out] o_data A pointer to an 8-byte integer to receive the scalar
+/// data. Assuming the item is located this variable is assigned by the call.
+/// In the event of an error the final state of \a o_data is not specified.
+///
+/// This API searches the SBE-XIP Table of Contents (TOC) for the item named
+/// \a i_id, assigning \a o_data from the image if the item is found and is a
+/// scalar value. Scalar values include 8- 32- and 64-bit integers and PORE
+/// addresses. Image data smaller than 64 bits are extracted as unsigned
+/// types, and it is the caller's responsibility to cast or convert the
+/// returned data as appropriate.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_get_scalar(void *i_image, const char* i_id, uint64_t* o_data);
+
+
+/// Get an integral element from a vector held in an SBE-XIP image
+///
+/// \param[in] i_image A pointer to an SBE-XIP image in host memory. The
+/// image is assumed to be consistent with the information contained in the
+/// header regarding the presence of and sizes of all sections. The image is
+/// also required to have been normalized.
+///
+/// \param[in] i_id A pointer to a 0-terminated ASCII string naming the item
+/// requested.
+///
+/// \param[in] i_index The index of the vector element to return.
+///
+/// \param[out] o_data A pointer to an 8-byte integer to receive the
+/// data. Assuming the item is located this variable is assigned by the call.
+/// In the event of an error the final state of \a o_data is not specified.
+///
+/// This API searches the SBE-XIP Table of Contents (TOC) for the \a i_index
+/// element of the item named \a i_id, assigning \a o_data from the image if
+/// the item is found, is a vector of an integral type, and the \a i_index is
+/// in bounds. Vector elements smaller than 64 bits are extracted as unsigned
+/// types, and it is the caller's responsibility to cast or convert the
+/// returned data as appropriate.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_get_element(void *i_image,
+ const char* i_id,
+ const uint32_t i_index,
+ uint64_t* o_data);
+
+
+/// Get string data from an SBE-XIP image
+///
+/// \param[in] i_image A pointer to an SBE-XIP image in host memory. The
+/// image is assumed to be consistent with the information contained in the
+/// header regarding the presence of and sizes of all sections. The image is
+/// also required to have been normalized.
+///
+/// \param[in] i_id A pointer to a 0-terminated ASCII string naming the item
+/// requested.
+///
+/// \param[out] o_data A pointer to a character pointer. Assuming the
+/// item is located this variable is assigned by the call to point to the
+/// string as it exists in the \a i_image. In the event of an error the final
+/// state of \a o_data is not specified.
+///
+/// This API searches the SBE-XIP Table of Contents (TOC) for the item named
+/// \a i_id, assigning \a o_data if the item is found and is a string. It is
+/// the caller's responsibility to copy the string from the \a i_image memory
+/// space if necessary.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_get_string(void *i_image, const char* i_id, char** o_data);
+
+
+/// Directly read 64-bit data from the image based on a PORE address
+///
+/// \param[in] i_image A pointer to an SBE-XIP image in host memory. The
+/// image is assumed to be consistent with the information contained in the
+/// header regarding the presence of and sizes of all sections.
+///
+/// \param[in] i_poreAddress A relocatable PORE address contained in the
+/// image, presumably of an 8-byte data area. The \a i_poreAddress is
+/// required to be 8-byte aligned, otherwise the SBE_XIP_ALIGNMENT_ERROR code
+/// is returned.
+///
+/// \param[out] o_data The 64 bit data in host format that was found at \a
+/// i_poreAddress.
+///
+/// This API is provided for applications that need to manipulate SBE-XIP
+/// images in terms of their relocatable PORE addresses. The API checks that
+/// the \a i_poreAddress is properly aligned and contained in the image, then
+/// reads the contents of \a i_poreAddress into \a o_data, performing
+/// image-to-host endianess conversion if required.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_read_uint64(const void *i_image,
+ const uint64_t i_poreAddress,
+ uint64_t* o_data);
+
+
+/// Set scalar data in an SBE-XIP image
+///
+/// \param[in,out] io_image A pointer to an SBE-XIP image in host memory.
+/// The image is assumed to be consistent with the information contained in
+/// the header regarding the presence of and sizes of all sections. The image
+/// is also required to have been normalized.
+///
+/// \param[in] i_id A pointer to a 0-terminated ASCII string naming the item
+/// to be modified.
+///
+/// \param[in] i_data The new scalar data.
+///
+/// This API searches the SBE-XIP Table of Contents (TOC) for the item named
+/// by \a i_id, updating the image from \a i_data if the item is found, has
+/// a scalar type and can be modified. For this API the scalar types include
+/// 8- 32- and 64-bit integers. Although PORE addresses are considered a
+/// scalar type for sbe_xip_get_scalar(), PORE addresses can not be modified
+/// by this API. The caller is responsible for ensuring that the \a i_data is
+/// of the correct size for the underlying data element in the image.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_set_scalar(void* io_image, const char* i_id, const uint64_t i_data);
+
+
+/// Set an integral element in a vector held in an SBE-XIP image
+///
+/// \param[in] i_image A pointer to an SBE-XIP image in host memory. The
+/// image is assumed to be consistent with the information contained in the
+/// header regarding the presence of and sizes of all sections. The image is
+/// also required to have been normalized.
+///
+/// \param[in] i_id A pointer to a 0-terminated ASCII string naming the item
+/// to be updated.
+///
+/// \param[in] i_index The index of the vector element to update.
+///
+/// \param[out] i_data The new vector element.
+///
+/// This API searches the SBE-XIP Table of Contents (TOC) for the \a i_index
+/// element of the item named \a i_id, update the image from \a i_data if the
+/// item is found, is a vector of an integral type, and the \a i_index is in
+/// bounds. The caller is responsible for ensuring that the \a i_data is of
+/// the correct size for the underlying data element in the image.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_set_element(void *i_image,
+ const char* i_id,
+ const uint32_t i_index,
+ const uint64_t i_data);
+
+
+/// Set string data in an SBE-XIP image
+///
+/// \param[in] i_image A pointer to an SBE-XIP image in host memory. The
+/// image is assumed to be consistent with the information contained in the
+/// header regarding the presence of and sizes of all sections. The image is
+/// also required to have been normalized.
+///
+/// \param[in] i_id A pointer to a 0-terminated ASCII string naming the item
+/// to be modified.
+///
+/// \param[in] i_data A pointer to the new string data.
+///
+/// This API searches the SBE-XIP Table of Contents (TOC) for the item named
+/// \a i_id, which must be a string variable. If found, then the string data
+/// in the image is overwritten with \a i_data. Strings are held 0-terminated
+/// in the image, and the SBE-XIP format does not maintain a record of the
+/// amount of memory allocated for an individual string. If a string is
+/// overwritten by a shorter string then the 'excess' storage is effectively
+/// lost. If the length of \a i_data is longer that the current strlen() of
+/// the string data then \a i_data is silently truncated to the first
+/// strlen(old_string) characters.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_set_string(void *io_image, const char* i_id, const char* i_data);
+
+
+/// Directly write 64-bit data into the image based on a PORE address
+///
+/// \param[in, out] io_image A pointer to an SBE-XIP image in host memory. The
+/// image is assumed to be consistent with the information contained in the
+/// header regarding the presence of and sizes of all sections.
+///
+/// \param[in] i_poreAddress A relocatable PORE address contained in the
+/// image, presumably of an 8-byte data area. The \a i_poreAddress is
+/// required to be 8-byte aligned, otherwise the SBE_XIP_ALIGNMENT_ERROR code
+/// is returned.
+///
+/// \param[in] i_data The 64 bit data in host format to be written to \a
+/// i_poreAddress.
+///
+/// This API is provided for applications that need to manipulate SBE-XIP
+/// images in terms of their relocatable PORE addresses. The API checks that
+/// the \a i_poreAddress is properly aligned and contained in the image, then
+/// updates the contents of \a i_poreAddress with \a i_data, performing
+/// host-to-image endianess conversion if required.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_write_uint64(void *io_image,
+ const uint64_t i_poreAddress,
+ const uint64_t i_data);
+
+
+/// Map over an SBE-XIP image Table of Contents
+///
+/// \param[in,out] io_image A pointer to an SBE-XIP image in host memory. The
+/// image is assumed to be consistent with the information contained in the
+/// header regarding the presence of and sizes of all sections. The image is
+/// also required to have been normalized.
+///
+/// \param[in] i_fn A pointer to a function to call on each TOC entry. The
+/// function has the prototype:
+///
+/// \code
+/// int (*i_fn)(void* io_image,
+/// const SbeXipItem* i_item,
+/// void* io_arg)
+/// \endcode
+///
+/// \param[in,out] io_arg The private argument of \a i_fn.
+///
+/// This API iterates over each entry of the TOC, calling \a i_fn with
+/// pointers to the image, an SbeXipItem* pointer, and a private argument. The
+/// iteration terminates either when all TOC entries have been mapped, or \a
+/// i_fn returns a non-zero code.
+///
+/// \retval 0 Success; All TOC entries were mapped, including the case that
+/// the .toc section is empty.
+///
+/// \revtal non-0 May be either one of the SBE-XIP image error codes (see \ref
+/// sbe_xip_image_errors), or a non-zero code from \a i_fn. Since the standard
+/// SBE_XIP return codes are > 0, application-defined codes should be < 0.
+int
+sbe_xip_map_toc(void* io_image,
+ int (*i_fn)(void* io_image,
+ const SbeXipItem* i_item,
+ void* io_arg),
+ void* io_arg);
+
+
+/// Find an SBE-XIP TOC entry
+///
+/// \param[in] i_image A pointer to an SBE-XIP image in host memory. The
+/// image is assumed to be consistent with the information contained in the
+/// header regarding the presence of and sizes of all sections. The image is
+/// also required to have been normalized.
+///
+/// \param[in] i_id A 0-byte terminated ASCII string naming the item to be
+/// searched for.
+///
+/// \param[out] o_item If the search is successful, then the object
+/// pointed to by \a o_item is filled in with the decoded form of the
+/// TOC entry for \a i_id. If the API returns a non-0 error code then the
+/// final state of the storage at \a o_item is undefined. This parameter may
+/// be suppied as 0, in which case sbe_xip_find() serves as a simple predicate
+/// on whether an item is indexded in the TOC.
+///
+/// This API searches the TOC of a normalized SBE-XIP image for the item named
+/// \a i_id, and if found, fills in the structure pointed to by \a
+/// o_item with a decoded form of the TOC entry. If the item is not found,
+/// the following two return codes may be considered non-error codes:
+///
+/// - SBE_XIP_ITEM_NOT_FOUND : No TOC record for \a i_id was found.
+///
+/// - SBE_XIP_DATA_NOT_PRESENT : The item appears in the TOC, however the
+/// section containing the data is no longer present in the image.
+///
+/// If the TOC section has been deleted from the image, then the search is
+/// restricted to the abbreviated TOC that indexes data in the .fixed section.
+/// In this case the \a o_item structure is marked with a 1 in the \a
+/// iv_partial field since the abbreviated TOC can not populate the entire
+/// SbeXipItem structure.
+///
+/// \note This API should typically only be used as a predicate, not as a way
+/// to access the image via the returned SbeXipItem structure. To obtain data
+/// from the image or update data in the image use the sbe_xip_get_*() and
+/// sbe_xip_set_*() APIs respectively.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_find(void* i_image,
+ const char* i_id,
+ SbeXipItem* o_item);
+
+
+/// Map over an SBE-XIP image .halt section
+///
+/// \param[in,out] io_image A pointer to an SBE-XIP image in host memory. The
+/// image is assumed to be consistent with the information contained in the
+/// header regarding the presence of and sizes of all sections.
+///
+/// \param[in] i_fn A pointer to a function to call on each entry in .halt.
+/// The function has the prototype:
+///
+/// \code
+/// int (*i_fn)(void* io_image,
+/// const uint64_t i_poreAddress,
+/// const char* i_rcString,
+/// void* io_arg)
+///
+/// \param[in,out] io_arg The private argument of \a i_fn.
+///
+/// This API iterates over each entry of the .halt section, calling \a i_fn
+/// with each HALT address, the string form of the return code associated with
+/// that HALT address, and a private argument. The iteration terminates either
+/// when all .halt entries have been mapped, or \a i_fn returns a non-zero
+/// code. The \a i_poreAddddress passed to \a i_fn is the full 48-bit
+/// relocatable PORE address.
+///
+/// \retval 0 Success, including the case that the image has no .halt section.
+///
+/// \revtal non-0 May be either one of the SBE-XIP image error codes (see \ref
+/// sbe_xip_image_errors), or any non-zero code from \a i_fn. Since the
+/// standard SBE_XIP return codes are > 0, application-defined codes should be
+/// < 0.
+int
+sbe_xip_map_halt(void* io_image,
+ int (*i_fn)(void* io_image,
+ const uint64_t i_poreAddress,
+ const char* i_rcString,
+ void* io_arg),
+ void* io_arg);
+
+
+/// Get the string from of a HALT code from an SBE-XIP image .halt section
+///
+/// \param[in,out] io_image A pointer to an SBE-XIP image in host memory. The
+/// image is assumed to be consistent with the information contained in the
+/// header regarding the presence of and sizes of all sections.
+///
+/// \param[in] i_poreAddress This is the 48-bit address found in the PC when
+/// the PORE halts. This address is actually 4 bytes beyond the actual HALT
+/// instruction, however for simplicity this is the address used to index the
+/// HALT.
+///
+/// \param[out] o_rcString The caller provides the address of a string-pointer
+/// variable which is updated with a pointer to the string form of the halt
+/// code associated with \a i_poreAddress (assuming a successful completion).
+///
+/// \retval 0 Success
+///
+/// \retval SBE_XIP_ITEM_NOT_FOUND The \a i_poreAddress is not associated
+/// with a halt code in .halt.
+///
+/// \revtal Other See \ref sbe_xip_image_errors
+int
+sbe_xip_get_halt(void* io_image,
+ const uint64_t i_poreAdress,
+ const char** o_rcString);
+
+
+/// Delete a section from an SBE-XIP image in host memory
+///
+/// \param[in,out] i_image A pointer to an SBE-XIP image in host memory. The
+/// image is assumed to be consistent with the information contained in the
+/// header regarding the presence of and sizes of all sections. The image is
+/// also required to have been normalized.
+///
+/// \param[in] i_sectionId Identifies the section to be deleted. See \ref
+/// sbe_xip_sections.
+///
+/// This API effectively deletes a section from an SBE-XIP image held in host
+/// memory. Unless the requested section \a i_section is already empty, only
+/// the final (highest address offset) section of the image may be deleted.
+/// Deleting the final section of the image means that the section size is set
+/// to 0, and the size of the image recorded in the header is reduced by the
+/// section size. This API does not check for or warn if other sections in
+/// the image reference the deleted section.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_delete_section(void* io_image, const int i_sectionId);
+
+
+/// Duplicate a section from an SBE-XIP image in host memory
+///
+/// \param[in,out] i_image A pointer to an SBE-XIP image in host memory. The
+/// image is assumed to be consistent with the information contained in the
+/// header regarding the presence of and sizes of all sections.
+///
+/// \param[in] i_sectionId Identifies the section to be duplicated. See \ref
+/// sbe_xip_sections.
+///
+/// \param[out] o_duplicate At exit, points to the newly allocated and
+/// initialized duplicate of the given section. The caller is responsible for
+/// free()-ing this memory when no longer required.
+///
+/// \param[out] o_size At exit, contains the size (in bytes) of the duplicated
+/// section.
+///
+/// This API creates a bytewise duplicate of a non-empty section into newly
+/// malloc()-ed memory. At exit \a o_duplicate points to the duplicate, and \i
+/// o_size is set the the size of the duplicated section. The caller is
+/// responsible for free()-ing the memory when no longer required. The
+/// pointer at \o_duplicate is set to NULL (0) and teh \a o_size is set to 0
+/// in the event of any failure.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_duplicate_section(const void* i_image,
+ const int i_sectionId,
+ void** o_duplicate,
+ uint32_t* size);
+
+
+/// Append binary data to an SBE-XIP image held in host memory
+///
+/// \param[in,out] io_image A pointer to an SBE-XIP image in host memory. The
+/// image is assumed to be consistent with the information contained in the
+/// header regarding the presence of and sizes of all sections. The image is
+/// also required to have been normalized.
+///
+/// \param[in] i_sectionId Identifies the section to contain the new data.
+///
+/// \param[in] i_data A pointer to the data to be appended to the image. If
+/// this pointer is NULL (0), then the effect is as if \a i_data were a
+/// pointer to an \a i_size array of 0 bytes.
+///
+/// \param[in] i_size The size of the data to be appended in bytes. If \a
+/// i_data is 0, then this is the number of bytes to clear.
+///
+/// \param[in] i_allocation The size of the memory region containing the
+/// image, measured from the first byte of the image. The call will fail if
+/// appending the new data plus any alignment padding would overflow the
+/// allocated memory.
+///
+/// \param[out] o_sectionOffset If non-0 at entry, then the API updates the
+/// location pointed to by \a o_sectionOffset with the offset of the first
+/// byte of the appended data within the indicated section.
+///
+/// This API copies data from \a i_data to the end of the indicated \a
+/// i_section. The section \a i_section must either be empty, or must be the
+/// final (highest address) section in the image. If the section is initially
+/// empty and \a i_size is non-0 then the section is created at the end of the
+/// image. The size of \a i_section and the size of the image are always
+/// adjusted to reflect the newly added data. This is a simple binary copy
+/// without any interpretation (e.g., endian-translation) of the copied data.
+/// The caller is responsible for insuring that the host memory area
+/// containing the SBE-XIP image is large enough to hold the newly appended
+/// data without causing addressing errors or buffer overrun errors.
+///
+/// The final parameter \a o_sectionOffset is optional, and may be passed as
+/// NULL (0) if the application does not require the information. This return
+/// value is provided to simplify typical use cases of this API:
+///
+/// - A scan program is appended to the image, or a run-time data area is
+/// allocated and cleared at the end of the image.
+///
+/// - Pointer variables in the image are updated with PORE addresses obtained
+/// via sbe_xip_section2pore(), or
+/// other procedure code initializes a newly allocated and cleared data area
+/// via host addresses obtained from sbe_xip_section2host().
+///
+/// Regarding alignment, note that the SBE-XIP format requires that sections
+/// maintain an initial alignment that varies by section, and the API will
+/// enforce these alignment constraints for all sections created by the API.
+/// All alignment is relative to the first byte of the image (\a io_image) -
+/// \e not to the current in-memory address of the image. By specification
+/// SBE-XIP images must be loaded at a 4K alignment in order for PORE hardware
+/// relocation to work, however the APIs don't require this 4K alignment for
+/// in-memory manipulation of images. Images to be executed on PoreVe will
+/// normally require at least 8-byte final aligment in order to guarantee that
+/// the PoreVe can execute an 8-byte fetch or load/store of the final
+/// doubleword.
+///
+/// \note If the TOC section is modified then the image is marked as having an
+/// unsorted TOC.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_append(void* io_image,
+ const int i_sectionId,
+ const void* i_data,
+ const uint32_t i_size,
+ const uint32_t i_allocation,
+ uint32_t* o_sectionOffset);
+
+
+/// Convert an SBE-XIP section offset to a relocatable PORE address
+///
+/// \param[in] i_image A pointer to an SBE-XIP image in host memory
+///
+/// \param[in] i_sectionId A valid SBE-XIP section identifier; The section
+/// must be non-empty.
+///
+/// \param[in] i_offset An offset (in bytes) within the section. At least one
+/// byte at \a i_offset must be currently allocated in the section.
+///
+/// \param[in] o_poreAddress The equivalent relocatable PORE address is
+/// returned via this pointer. Since valid PORE addresses are always either
+/// 4-byte (code) or 8-byte (data) aligned, this API checks the aligment of
+/// the translated address and returns SBE_XIP_ALIGNMENT_ERROR if the PORE
+/// address is not at least 4-byte aligned. Note that the translated address
+/// is still returned even if incorrectly aligned.
+///
+/// This API is typically used to translate section offsets returned from
+/// sbe_xip_append() into relocatable PORE addresses.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_section2pore(const void* i_image,
+ const int i_sectionId,
+ const uint32_t i_offset,
+ uint64_t* o_poreAddress);
+
+
+/// Convert an SBE-XIP relocatable PORE address to a host memory address
+///
+/// \param[in] i_image A pointer to an SBE-XIP image in host memory.
+///
+/// \param[in] i_poreAddress A relocatable PORE address putatively addressing
+/// relocatable memory contained in the image.
+///
+/// \param[out] o_hostAddress The API updates the location pointed to by \a
+/// o_hostAddress with the host address of the memory addressed by \a
+/// i_poreAddress. In the event of an error (non-0 return code) the final
+/// content of \a o_hostAddress is undefined.
+///
+/// This API is typically used to translate relocatable PORE addresses stored
+/// in the SBE-XIP image into the equivalent host address of the in-memory
+/// image, allowing host-code to manipulate arbitrary data structures in the
+/// image. If the \a i_poreAddress does not refer to memory within the image
+/// (as determined by the link address and image size) then the
+/// SBE_XIP_INVALID_ARGUMENT error code is returned.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_pore2host(const void* i_image,
+ const uint64_t i_poreAddress,
+ void** o_hostAddress);
+
+
+/// Convert an SBE-XIP relocatable PORE address to section Id and offset
+///
+/// \param[in] i_image A pointer to an SBE-XIP image in host memory.
+///
+/// \param[in] i_poreAddress A relocatable PORE address putatively addressing
+/// relocatable memory contained in the image.
+///
+/// \param[out] o_section The API updates the location pointed to by \a
+/// o_section with the section Id of the memory addressed by \a
+/// i_poreAddress. In the event of an error (non-0 return code) the final
+/// content of \a o_section is undefined.
+///
+/// \param[out] o_offset The API updates the location pointed to by \a
+/// o_offset with the byte offset of the memory addressed by \a i_poreAddress
+/// within \a o_section. In the event of an error (non-0 return code) the
+/// final content of \a o_offset is undefined.
+///
+/// This API is typically used to translate relocatable PORE addresses stored
+/// in the SBE-XIP image into the equivalent section + offset form, allowing
+/// host-code to manipulate arbitrary data structures in the image. If the \a
+/// i_poreAddress does not refer to memory within the image (as determined by
+/// the link address and image size) then the SBE_XIP_INVALID_ARGUMENT error
+/// code is returned.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_pore2section(const void* i_image,
+ const uint64_t i_poreAddress,
+ int* o_section,
+ uint32_t* o_offset);
+
+
+/// Convert an in-memory SBE-XIP host address to a relocatable PORE address
+///
+/// \param[in] i_image A pointer to an SBE-XIP image in host memory
+///
+/// \param[in] i_hostAddress A host address addressing data within the image.
+///
+/// \param[out] o_poreAddress The API updates the location pointed to by \a
+/// o_poreAddress with the equivelent relocatable PORE address of the memory
+/// addressed by i_hostAddress. Since valid PORE addresses are always either
+/// 4-byte (code) or 8-byte (data) aligned, this API checks the aligment of
+/// the translated address and returns SBE_XIP_ALIGNMENT_ERROR if the PORE
+/// address is not at least 4-byte aligned. Note that the translated address
+/// is still returned evn if incorrectly aligned.
+///
+/// This API is provided as a convenient way to convert host memory addresses
+/// for an in-memory SBE-XIP image into PORE addresses correctly relocated for
+/// the image, for example to update pointer variables in the image. If the
+/// \a i_hostAddress does not refer to memory within the image (as determined
+/// by the image address and image size) then the SBE_XIP_INVALID_ARGUMENT
+/// error code is returned.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_host2pore(const void* i_image,
+ void* i_hostAddress,
+ uint64_t* i_poreAddress);
+
+
+/// \defgroup sbe_xip_image_errors Error codes from SBE-XIP image APIs
+///
+/// @{
+
+/// A putative SBE-XIP image does not have the correct magic number, or
+/// contains some other major inconsistency.
+#define SBE_XIP_IMAGE_ERROR 1
+
+/// The TOC may be missing, partially present or may have an alignment problem.
+#define SBE_XIP_TOC_ERROR 2
+
+/// A named item was not found in the SBE-XIP TOC, or a putative HALT address
+/// is not associated with a halt code in .halt.
+#define SBE_XIP_ITEM_NOT_FOUND 3
+
+/// A named item appears in the SBE-XIP TOC, but the data is not present in
+/// the image. This error can occur if sections have been deleted from the
+/// image.
+#define SBE_XIP_DATA_NOT_PRESENT 4
+
+/// A named item appears in the SBE-XIP TOC, but the data can not be
+/// modified. This error will occur if an attempt is made to modify an
+/// address-only entry.
+#define SBE_XIP_CANT_MODIFY 5
+
+/// A direct or implied argument is invalid, e.g. an illegal data type or
+/// section identifier, or an address not contained within the image.
+#define SBE_XIP_INVALID_ARGUMENT 6
+
+/// A data type mismatch or an illegal type was specified or implied for an
+/// operation.
+#define SBE_XIP_TYPE_ERROR 7
+
+/// A bug in an SBE-XIP image API
+#define SBE_XIP_BUG 8
+
+/// The image must first be normalized with sbe_xip_normalize().
+#define SBE_XIP_NOT_NORMALIZED 9
+
+/// Attempt to delete a non-empty section that is not the final section of the
+/// image, or an attempt to append data to a non-empty section that is not the
+/// final section of the image, or an attempt to operate on an empty section
+/// for those APIs that prohibit this.
+#define SBE_XIP_SECTION_ERROR 10
+
+/// An address translation API returned a PORE address that was not at least
+/// 4-byte aligned, or alignment violations were observed by
+/// sbe_xip_validate() or sbe_xip_append().
+#define SBE_XIP_ALIGNMENT_ERROR 11
+
+/// An API that performs dynamic memory allocation was unable to allocate
+/// memory.
+#define SBE_XIP_NO_MEMORY 12
+
+/// Attempt to get or set a vector element with an index that is outside of
+/// the declared bounds of the vector.
+#define SBE_XIP_BOUNDS_ERROR 13
+
+/// Attempt to grow the image past its defined memory allocation
+#define SBE_XIP_WOULD_OVERFLOW 14
+
+/// Error associated with the disassembler occured.
+#define SBE_XIP_DISASSEMBLER_ERROR 15
+
+/// hash collision creating the .fixed_toc section
+#define SBE_XIP_HASH_COLLISION 16
+
+/// Applications can expand this macro to declare an array of string forms of
+/// the error codes if desired.
+#define SBE_XIP_ERROR_STRINGS(var) \
+ const char* var[] = { \
+ "Success", \
+ "SBE_XIP_IMAGE_ERROR", \
+ "SBE_XIP_TOC_ERROR", \
+ "SBE_XIP_ITEM_NOT_FOUND", \
+ "SBE_XIP_DATA_NOT_PRESENT", \
+ "SBE_XIP_CANT_MODIFY", \
+ "SBE_XIP_INVALID_ARGUMENT", \
+ "SBE_XIP_TYPE_ERROR", \
+ "SBE_XIP_BUG", \
+ "SBE_XIP_NOT_NORMALIZED", \
+ "SBE_XIP_SECTION_ERROR", \
+ "SBE_XIP_ALIGNMENT_ERROR", \
+ "SBE_XIP_NO_MEMORY", \
+ "SBE_XIP_BOUNDS_ERROR", \
+ "SBE_XIP_WOULD_OVERFLOW", \
+ "SBE_XIP_DISASSEMBLER_ERROR", \
+ "SBE_XIP_HASH_COLLISION", \
+ }
+
+/// Applications can use this macro to safely index the array of error
+/// strings.
+#define SBE_XIP_ERROR_STRING(var, n) \
+ ((((n) < 0) || ((n) > (int)(sizeof(var) / sizeof(char*)))) ? \
+ "Bug : Invalid SBE-XIP error code" : var[n])
+
+/// @}
+
+/// Disassembler error codes.
+#define DIS_IMAGE_ERROR 1
+#define DIS_MEMORY_ERROR 2
+#define DIS_DISASM_ERROR 3
+#define DIS_RING_NAME_ADDR_MATCH_SUCCESS 4
+#define DIS_RING_NAME_ADDR_MATCH_FAILURE 5
+#define DIS_TOO_MANY_DISASM_WARNINGS 6
+#define DIS_DISASM_TROUBLES 7
+
+#define DIS_ERROR_STRINGS(var) \
+ const char* var[] = { \
+ "Success", \
+ "DIS_IMAGE_ERROR", \
+ "DIS_MEMORY_ERROR", \
+ "DIS_DISASM_ERROR", \
+ "DIS_RING_NAME_ADDR_MATCH_SUCCESS", \
+ "DIS_RING_NAME_ADDR_MATCH_FAILURE", \
+ "DIS_TOO_MANY_DISASM_WARNINGS", \
+ "DIS_DISASM_TROUBLES", \
+ }
+
+#define DIS_ERROR_STRING(var, n) \
+ ((((n) < 0) || ((n) > (int)(sizeof(var) / sizeof(char*)))) ? \
+ "Bug : Invalid DIS error code" : var[n])
+
+#if 0
+{ /* So __cplusplus doesn't mess w/auto-indent */
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __ASSEMBLER__
+
+
+////////////////////////////////////////////////////////////////////////////
+// Assembler Definitions
+////////////////////////////////////////////////////////////////////////////
+
+#ifdef __ASSEMBLER__
+
+/// Create an XIP TOC entry
+///
+/// \param[in] index The string form of the \a index symbol is created and
+/// linked from the TOC entry to allow external search procedures to locate
+/// the \a address.
+///
+/// \param[in] type One of the SBE_XIP_* type constants; See \ref
+/// sbe_xip_toc_types.
+///
+/// \param[in] address The address of the idexed code or data; This wlll
+/// typically be a symbol.
+///
+/// \param[in] elements <Optional> For vector types, number of elements in the
+/// vector, which is limited to an 8-bit unsigned integer. This parameter
+/// defaults to 1 which indicates a scalar type. Declaring a vector with 0
+/// elements disables bounds checking on vector accesses, and can be used if
+/// very large or indeterminate sized vectors are required. The TOC format
+/// does not support vectors of strings or addresses.
+///
+/// The \c .xip_toc macro creates a XIP Table of Contents (TOC) structure in
+/// the \c .toc section, as specified by the parameters. This macro is
+/// typically not used directly in assembly code. Instead programmers should
+/// use .xip_quad, .xip_quada, .xip_quadia, .xip_address, .xip_string or
+/// .xip_cvs_revision.
+
+ .macro .xip_toc, index:req, type:req, address:req, elements=1
+
+ .if (((\type) < 1) || ((\type) > SBE_XIP_MAX_TYPE_INDEX))
+ .error ".xip_toc : Illegal type index"
+ .endif
+
+ // First push into the .strings section to lay down the
+ // string form of the index name under a local label.
+
+ .pushsection .strings
+7667862:
+ .asciz "\index"
+ .popsection
+
+ // Now the 12-byte TOC entry is created. Push into the .toc section
+ // and lay down the first 4 bytes which are always a pointer to the
+ // string just declared. The next 4 bytes are the address of the data
+ // (or the address itself in the case of address types). The final 4
+ // bytes are the type, section (always 0 prior to normalization),
+ // number of elements, and a padding byte.
+
+ .pushsection .toc
+
+ .long 7667862b, (\address)
+ .byte (\type), 0, (\elements), 0
+
+ .popsection
+
+ .endm
+
+
+/// Allocate and initialize 64-bit global scalar or vector data and create the
+/// TOC entry.
+///
+/// \param[in] symbol The name of the scalar or vector; this name is also used
+/// as the TOC index of the data.
+///
+/// \param[in] init The initial value of (each element of) the data.
+/// This is a 64-bit integer; To allocate address pointers use .xip_quada.
+///
+/// \param[in] elements The number of 64-bit elements in the data structure,
+/// defaulting to 1, with a maximum value of 255.
+///
+/// \param[in] section The section where the data will be allocated,
+/// default depends on the memory space
+
+ .macro .xip_quad, symbol:req, init:req, elements=1, section
+
+ ..xip_quad_helper .quad, \symbol, (\init), (\elements), \section
+
+ .endm
+
+
+/// Allocate and initialize 64-bit global scalar or vector data containing a
+/// relocatable address in and create the TOC entry.
+///
+/// \param[in] symbol The name of the scalar or vector; this name is also used
+/// as the TOC index of the data.
+///
+/// \param[in] init The initial value of (each element of) the data. This
+/// will typically be a symbolic address. If the intention is to define an
+/// address that will always be filled in later by image manipulation tools,
+/// then use the .xip_quad macro with a 0 initial value.
+///
+/// \param[in] elements The number of 64-bit elements in the data structure,
+/// defaulting to 1, with a maximum value of 255.
+///
+/// \param[in] section The section where the data will be allocated,
+/// default depends on the memory space
+
+ .macro .xip_quada, symbol:req, offset:req, elements=1, section
+
+ ..xip_quad_helper .quada, \symbol, (\offset), (\elements), \section
+
+ .endm
+
+
+/// Helper for .xip_quad and .xip_quada
+
+ .macro ..xip_quad_helper, directive, symbol, init, elements, section
+
+ .if (((\elements) < 1) || ((\elements) > 255))
+ .error "The number of vector elements must be in the range 1..255"
+ .endif
+
+ ..xip_pushsection \section
+ .balign 8
+
+ .global \symbol
+\symbol\():
+ .rept (\elements)
+ \directive (\init)
+ .endr
+
+ .popsection
+
+ .xip_toc \symbol, SBE_XIP_UINT64, \symbol, (\elements)
+
+ .endm
+
+
+/// Allocate and initialize 64-bit global scalar or vector data containing
+/// full 64-bit addresses and create a TOC entry
+///
+/// \param[in] symbol The name of the scalar or vector; this name is also used
+/// as the TOC index of the data.
+///
+/// \param[in] space A valid PORE memory space descriptor
+///
+/// \param[in] offset A 32-bit relocatable offset
+///
+/// \param[in] elements The number of 64-bit elements in the data structure,
+/// defaulting to 1, with a maximum value of 255.
+///
+/// \param[in] section The section where the data will be allocated,
+/// default depends on the memory space
+
+ .macro .xip_quadia, symbol:req, space:req, offset:req, \
+ elements=1, section
+
+ .if (((\elements) < 1) || ((\elements) > 255))
+ .error "The number of vector elements must be in the range 1..255"
+ .endif
+
+ ..xip_pushsection \section
+ .balign 8
+
+ .global \symbol
+\symbol\():
+ .rept (\elements)
+ .quadia (\space), (\offset)
+ .endr
+
+ .popsection
+
+ .xip_toc \symbol, SBE_XIP_UINT64, \symbol, (\elements)
+
+ .endm
+
+/// Default push into .ipl_data unless in an OCI space, then .data
+
+ .macro ..xip_pushsection, section
+
+ .ifnb \section
+ .pushsection \section
+ .else
+ .if (_PGAS_DEFAULT_SPACE == PORE_SPACE_OCI)
+ .pushsection .data
+ .else
+ .pushsection .ipl_data
+ .endif
+ .endif
+
+ .balign 8
+
+ .endm
+
+/// Allocate and initialize a string in .strings
+///
+/// \param[in] index The string will be stored in the TOC using this index
+/// symbol.
+///
+/// \param[in] string The string to be allocated in .strings. String space is
+/// fixed once allocated. Strings designed to be overwritten by external tools
+/// should be allocated to be as long as eventually needed (e.g., by a string
+/// of blanks.)
+
+ .macro .xip_string, index:req, string:req
+
+ .pushsection .strings
+7874647:
+ .asciz "\string"
+ .popsection
+
+ .xip_toc \index, SBE_XIP_STRING, 7874647b
+
+ .endm
+
+
+/// Allocate and initialize a CVS Revison string in .strings
+///
+/// \param[in] index The string will be stored in the TOC using this index
+/// symbol.
+///
+/// \param[in] string A CVS revision string to be allocated in .strings. CVS
+/// revision strings are formatted by stripping out and only storing the
+/// actual revision number :
+///
+/// \code
+/// "$Revision <n>.<m> $" -> "<n>.<m>"
+/// \endcode
+
+
+ .macro .xip_cvs_revision, index:req, string:req
+
+ .pushsection .strings
+7874647:
+ ..cvs_revision_string "\string"
+ .popsection
+
+ .xip_toc \index, SBE_XIP_STRING, 7874647b
+
+ .endm
+
+
+/// Shorthand to create a TOC entry for an address
+///
+/// \param[in] index The symbol will be indexed as this name
+///
+/// \param[in] symbol <Optional> The symbol to index; by default the same as
+/// the index.
+
+ .macro .xip_address, index:req, symbol
+
+ .ifb \symbol
+ .xip_toc \index, SBE_XIP_ADDRESS, \index
+ .else
+ .xip_toc \index, SBE_XIP_ADDRESS, \symbol
+ .endif
+
+ .endm
+
+
+/// Edit and allocate a CVS revision string
+///
+/// CVS revision strings are formatted by stripping out and only storing the
+/// actual revision number :
+/// \code
+/// "$Revision <n>.<m> $" -> "<n>.<m>"
+/// \endcode
+
+ .macro ..cvs_revision_string, rev:req
+ .irpc c, \rev
+ .ifnc "\c", "$"
+ .ifnc "\c", "R"
+ .ifnc "\c", "e"
+ .ifnc "\c", "v"
+ .ifnc "\c", "i"
+ .ifnc "\c", "s"
+ .ifnc "\c", "i"
+ .ifnc "\c", "o"
+ .ifnc "\c", "n"
+ .ifnc "\c", ":"
+ .ifnc "\c", " "
+ .ascii "\c"
+ .endif
+ .endif
+ .endif
+ .endif
+ .endif
+ .endif
+ .endif
+ .endif
+ .endif
+ .endif
+ .endif
+ .endr
+ .byte 0
+ .endm
+
+#endif // __ASSEMBLER__
+
+#endif // __SBE_XIP_TOC_H
diff --git a/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/p8_delta_scan_rw.h b/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/p8_delta_scan_rw.h
index 6cdf89108..a0466c2ef 100644
--- a/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/p8_delta_scan_rw.h
+++ b/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/p8_delta_scan_rw.h
@@ -22,16 +22,22 @@
* IBM_PROLOG_END_TAG
*/
//***** IMPORTANT - Assumptions (you may have to change these settings) ******
-#define ASM_RS4_LAUNCH_BUF_SIZE 24 // Byte size of binary RS4 launch buffer w/last two
- // nops removed.
-#define OVERRIDE_OFFSET 8 // Byte offset of forward pointer's addr relative
- // to base forward pointer's addr.
-#define SLW_MS_MAX_BUF_SIZE 50000000 // Max 50MB for SLW mainstore image.
+#define ASM_RS4_LAUNCH_BUF_SIZE 24 // Byte size of binary RS4 launch buffer w/last two
+ // nops removed. Must always be 8-byte aligned.
+#define OVERRIDE_OFFSET 8 // Byte offset of forward pointer's addr relative
+ // to base forward pointer's addr.
+#define SIZE_IMAGE_BUF_MAX 50000000 // Max 50MB image buffer size.
+#define SIZE_IMAGE_CENTAUR_MAX 5000000 // Max 5MB image buffer size.
+#define SCOM_REG_MASK 0x00ffffff // Scom register mask (within a chiplet)
+#define CID_MASK 0xff000000 // Chiplet ID mask
+#define CID_EX_LOW 0x10 // Lowest EX chiplet addr
+#define CID_EX_HIGH 0x1f // Highest EX chiplet addr
+
/***** Scan Control Regs *****/
#define P8_PORE_CLOCK_CONTROLLER_REG 0x00030007 // Addr of clock ctrl scom reg
#define P8_PORE_SHIFT_REG 0x00038000 // Addr of scom reg that does scan ring shifting
-#define P8_SCAN_CHECK_WORD 0xA5A55A5A // Header check word
+#define P8_SCAN_CHECK_WORD 0xA5A55A5A // Header check word
/***** Ring state *****/
#define MAX_RING_SIZE 1000000 // This is the max binary ring size in bits
@@ -42,28 +48,44 @@
#define PRINT_WF_DIS // Causes wf inline code to be disassembled and written to file.
/***** Return codes *****/
-#define DSLWB_RING_SEARCH_MATCH 0
-#define DSLWB_RING_SEARCH_EXHAUST_MATCH 30
-#define DSLWB_RING_SEARCH_NO_MATCH 31
-#define DSLWB_RING_SEARCH_MESS 32
-#define DSLWB_SLWB_SUCCESS 0
-#define DSLWB_SLWB_NO_RING_MATCH 40
-#define DSLWB_SLWB_DX_ERROR 41
-#define DSLWB_SLWB_WF_ERROR 42
-#define DSLWB_SLWB_WF_IMAGE_ERROR 43
-#define DSLWB_SLWB_IMAGE_ERROR 44
-#define DSLWB_SLWB_UNKNOWN_ERROR 45
-#define IMGBUILD_SUCCESS 0 // Successful image build.
-#define IMGBUILD_ERR_MEMORY 20 // Memory allocation error.
-#define IMGBUILD_ERR_XIP_MISC 25 // Miscellaneous XIP image error.
-#define IMGBUILD_ERR_SECTION_DELETE 50 // Err assoc w/deleting ELF section.
-#define IMGBUILD_ERR_APPEND 51 // Err assoc w/appending to ELF section.
-#define IMGBUILD_ERR_INCOMPLETE_IMG_BUILD 52 // The image was built, but with errors.
-#define IMGBUILD_ERR_FWD_BACK_PTR_MESS 53 // Forward or backward pointer mess.
-#define IMGBUILD_ERR_KEYWORD_NOT_FOUND 54 // Image keyword not found.
-#define IMGBUILD_ERR_MISALIGNED_RING_LAYOUT 55 // Ring layout is misaligned.
-#define IMGBUILD_ERR_IMAGE_TOO_LARGE 56 // Image too large. Exceeded max size.
-#define IMGBUILD_ERR_CHECK_CODE 60 // Coding problem - impossible state.
+#define DSLWB_RING_SEARCH_MATCH 0
+#define DSLWB_RING_SEARCH_EXHAUST_MATCH 30
+#define DSLWB_RING_SEARCH_NO_MATCH 31
+#define DSLWB_RING_SEARCH_MESS 32
+#define DSLWB_SLWB_SUCCESS 0
+#define DSLWB_SLWB_NO_RING_MATCH 40
+#define DSLWB_SLWB_DX_ERROR 41
+#define DSLWB_SLWB_WF_ERROR 42
+#define DSLWB_SLWB_WF_IMAGE_ERROR 43
+#define DSLWB_SLWB_IMAGE_ERROR 44
+#define DSLWB_SLWB_UNKNOWN_ERROR 45
+#define IMGBUILD_SUCCESS 0 // Successful image build.
+#define IMGBUILD_ERR_CHECK_CODE 2 // Coding problem.
+#define IMGBUILD_ERR_MEMORY 4 // Memory allocation error.
+#define IMGBUILD_INVALID_IMAGE 10 // Invalid image.
+#define IMGBUILD_IMAGE_SIZE_MISMATCH 11 // Mismatch between image sizes.
+#define IMGBUILD_ERR_PORE_INLINE_ASM 20 // Err assoc w/inline assembler.
+#define IMGBUILD_ERR_SECTION_DELETE 50 // Err assoc w/deleting ELF section.
+#define IMGBUILD_ERR_APPEND 51 // Err assoc w/appending to ELF section.
+#define IMGBUILD_ERR_INCOMPLETE_IMG_BUILD 52 // The image was built, but with errors.
+#define IMGBUILD_ERR_FWD_BACK_PTR_MESS 53 // Forward or backward pointer mess.
+#define IMGBUILD_ERR_KEYWORD_NOT_FOUND 54 // Image keyword not found.
+#define IMGBUILD_ERR_MISALIGNED_RING_LAYOUT 55 // Ring layout is misaligned.
+#define IMGBUILD_ERR_IMAGE_TOO_LARGE 56 // Image too large. Exceeded max size.
+#define IMGBUILD_ERR_XIP_MISC 57 // Miscellaneous XIP image error.
+#define IMGBUILD_ERR_RS4_DECOMPRESS 58 // Error during RS4 decompression.
+#define IMGBUILD_ERR_PORE_INLINE 60 // Pore inline error.
+#define IMGBUILD_ERR_RAM_INVALID_PARM 65 // Invalid Ramming parameter.
+#define IMGBUILD_ERR_RAM_TABLE_FAIL 66 // Unsuccessful RAM table build.
+#define IMGBUILD_ERR_SCOM_INVALID_PARM 70 // Invalid Scomming parameter.
+#define IMGBUILD_ERR_SCOM_HDRS_NOT_SYNCD 72 // Scom headers out of sync.
+#define IMGBUILD_ERR_SCOM_ENTRY_NOT_FOUND 74 // Scom entry not found (OR/AND oper.)
+#define IMGBUILD_ERR_SCOM_REPEAT_ENTRIES 76 // Repeat entries not allow.
+#define IMGBUILD_ERR_SCOM_TABLE_FAIL 79 // Unsuccessful SCOM table build.
+
+#ifdef SLW_COMMAND_LINE_RAM
+#define SLW_COMMAND_LINE
+#endif
#ifdef __FAPI
#define MY_INF(_fmt_, _args_...) FAPI_INF(_fmt_, ##_args_)
@@ -73,28 +95,42 @@
#define MY_ERR(_fmt_, _args_...) FAPI_INF(_fmt_, ##_args_)
#endif // End of SLW_COMMAND_LINE
#define MY_DBG(_fmt_, _args_...) FAPI_DBG(_fmt_, ##_args_)
-#else
+#else // End of __FAPI
+#ifdef SLW_COMMAND_LINE
#define MY_INF(_fmt_, _args_...) fprintf(stdout, _fmt_, ##_args_)
#define MY_ERR(_fmt_, _args_...) fprintf(stderr, _fmt_, ##_args_)
#define MY_DBG(_fmt_, _args_...) fprintf(stdout, _fmt_, ##_args_)
-#endif // End of FAPI
+#else // End of SLW_COMMAND_LINE
+#define MY_INF(_fmt_, _args_...)
+#define MY_ERR(_fmt_, _args_...)
+#define MY_DBG(_fmt_, _args_...)
+#endif // End of not(__FAPI) & not(SLW_COMMAND_LINE)
+#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+
#ifdef SLW_COMMAND_LINE
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#endif //End of SLW_COMMAND_LINE
+
#ifndef SLW_BUILD_WF_P0_FIX
#include "pore_bitmanip.H"
#endif // SLW_BUILD_WF_P0_FIX
-#include "p8_pore_api.h"
-#include "p8_pore_static_data.h"
+
+//#include "p8_pore_api.h"
+//#include "p8_pore_static_data.h"
+
+#ifndef SLW_COMMAND_LINE_RAM
#include "p8_scan_compression.H"
+#endif
+
#include "sbe_xip_image.h"
+
#undef __PORE_INLINE_ASSEMBLER_C__
#include "pore_inline.h"
@@ -102,6 +138,9 @@
extern "C" {
#endif
+
+#ifndef SLW_COMMAND_LINE_RAM
+
// Info:
// DeltaRingLayout describes the sequential order of the content in the compressed delta
// ring blocks in the .initf section in the SBE-XIP images.
@@ -115,103 +154,114 @@ extern "C" {
// - {rs4Delta} must start on a double-word bournday (see earlier rule how to do that).
//
typedef struct {
- uint64_t entryOffset;
- uint64_t backItemPtr;
- uint32_t sizeOfThis;
- uint32_t sizeOfMeta; // Exact size of meta data. Arbitrary size. Not null terminated.
- uint32_t ddLevel;
- uint8_t sysPhase;
- uint8_t override;
- uint8_t reserved1;
- uint8_t reserved2;
- char *metaData; // Arbitrary size. Extra bytes to next alignment are random or 0s.
- uint32_t *rs4Launch; // Code. Must be 4-byte aligned.
- uint32_t *rs4Delta; // Data. Must be 8-byte aligned.
- uint32_t *wfInline; // Code. Must be 4-byte aligned.
+ uint64_t entryOffset;
+ uint64_t backItemPtr;
+ uint32_t sizeOfThis;
+ uint32_t sizeOfMeta; // Exact size of meta data. Arbitrary size. Not null terminated.
+ uint32_t ddLevel;
+ uint8_t sysPhase;
+ uint8_t override;
+ uint8_t reserved1;
+ uint8_t reserved2;
+ char *metaData; // Arbitrary size. Extra bytes to next alignment are random or 0s.
+ uint32_t *rs4Launch; // Code. Must be 4-byte aligned. Actually should be 8-B align!
+ uint32_t *rs4Delta; // Data. Must be 8-byte aligned.
+ uint32_t *wfInline; // Code. Must be 4-byte aligned. Actually should be 8-B align!
} DeltaRingLayout;
typedef struct {
- uint32_t sizeOfData;
- char data[];
+ uint32_t sizeOfData;
+ char data[];
} MetaData;
-int p8_ipl_build( void *i_imageIn,
- uint32_t i_ddLevel,
- void *i_imageOut,
- uint32_t i_sizeImageOutMax);
-
-int get_ring_layout_from_image2( const void *i_imageIn,
- uint32_t i_ddLevel,
- uint8_t i_sysPhase,
- DeltaRingLayout **o_rs4RingLayout,
- void **nextRing);
-
-int write_ring_block_to_image( void *io_image,
- DeltaRingLayout *i_ringBlock,
- uint32_t i_sizeImageMax);
-
-int gen_ring_delta_state(
- uint32_t bitLen,
- uint32_t *i_init,
- uint32_t *i_alter,
- uint32_t *o_delta,
- uint32_t verbose);
-
-int write_delta_ring_to_image(
- char *i_fnImage,
- CompressedScanData *i_RS4,
- uint32_t i_ddLevel,
- uint8_t i_sysPhase,
- uint8_t i_override,
- char *i_varName,
- char *i_fnMetaData,
- uint32_t verbose);
+int p8_centaur_build( void *i_imageIn,
+ uint32_t i_ddLevel,
+ void *i_imageOut,
+ uint32_t i_sizeImageOutMax);
+
+int p8_ipl_build( void *i_imageIn,
+ uint32_t i_ddLevel,
+ void *i_imageOut,
+ uint32_t i_sizeImageOutMax);
+
+int get_ring_layout_from_image2( const void *i_imageIn,
+ uint32_t i_ddLevel,
+ uint8_t i_sysPhase,
+ DeltaRingLayout **o_rs4RingLayout,
+ void **nextRing);
+
+int write_ring_block_to_image( void *io_image,
+ DeltaRingLayout *i_ringBlock,
+ uint32_t i_sizeImageMax);
+
+int gen_ring_delta_state(
+ uint32_t bitLen,
+ uint32_t *i_init,
+ uint32_t *i_alter,
+ uint32_t *o_delta,
+ uint32_t verbose);
+
+int write_delta_ring_to_image(
+ char *i_fnImage,
+ CompressedScanData *i_RS4,
+ uint32_t i_ddLevel,
+ uint8_t i_sysPhase,
+ uint8_t i_override,
+ char *i_varName,
+ char *i_fnMetaData,
+ uint32_t verbose);
int get_delta_ring_from_image(
- char *i_fnImage,
- char *i_varName,
- uint32_t i_ddLevel,
- uint8_t i_sysPhase,
- uint8_t i_override,
- MetaData **o_metaData,
- CompressedScanData **o_deltaRingRS4,
- uint32_t verbose);
+ char *i_fnImage,
+ char *i_varName,
+ uint32_t i_ddLevel,
+ uint8_t i_sysPhase,
+ uint8_t i_override,
+ MetaData **o_metaData,
+ CompressedScanData **o_deltaRingRS4,
+ uint32_t verbose);
int write_wiggle_flip_to_image(
- void *io_imageOut,
- uint32_t *i_sizeImageMaxNew,
- DeltaRingLayout *i_ringLayout,
- uint32_t *i_wfInline,
- uint32_t i_wfInlineLenInWords);
-
-int get_ring_layout_from_image(
- const void *i_imageIn,
- uint32_t i_ddLevel,
- uint8_t i_sysPhase,
- DeltaRingLayout *o_rs4RingLayout,
- void **nextRing);
-
-int create_wiggle_flip_prg(
+ void *io_imageOut,
+ uint32_t *i_sizeImageMaxNew,
+ DeltaRingLayout *i_ringLayout,
+ uint32_t *i_wfInline,
+ uint32_t i_wfInlineLenInWords);
+
+int get_ring_layout_from_image(
+ const void *i_imageIn,
+ uint32_t i_ddLevel,
+ uint8_t i_sysPhase,
+ DeltaRingLayout *o_rs4RingLayout,
+ void **nextRing);
+
+int create_wiggle_flip_prg(
uint32_t *i_deltaRing,
uint32_t i_ringBitLen,
uint32_t i_scanSelectData,
- uint32_t i_chipletID,
+ uint32_t i_chipletID,
uint32_t **o_wfInline,
uint32_t *o_wfInlineLenInWords);
int append_empty_section(
- void *io_image,
- uint32_t *i_sizeImageMaxNew,
- uint32_t i_sectionId,
- uint32_t i_sizeSection);
+ void *io_image,
+ uint32_t *i_sizeImageMaxNew,
+ uint32_t i_sectionId,
+ uint32_t i_sizeSection);
+
+int initialize_slw_section(
+ void *io_image,
+ uint32_t *i_sizeImageMaxNew);
void cleanup(
- void *buf1=NULL,
- void *buf2=NULL,
- void *buf3=NULL,
- void *buf4=NULL,
- void *buf5=NULL);
-
+ void *buf1=NULL,
+ void *buf2=NULL,
+ void *buf3=NULL,
+ void *buf4=NULL,
+ void *buf5=NULL);
+
+#endif // End of not(SLW_COMMAND_LINE_RAM)
+
// Byte-reverse a 32-bit integer if on an LE machine
inline uint32_t myRev32(const uint32_t i_x)
{
@@ -256,6 +306,12 @@ inline uint64_t myRev64(const uint64_t i_x)
return rx;
}
+// N-byte align an address, offset or size (aos)
+inline uint64_t myByteAlign( const uint8_t nBytes, const uint64_t aos)
+{
+ return (aos+nBytes-1)/nBytes*nBytes;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/p8_image_help.C b/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/p8_image_help.C
index 6f0fe7af2..c2b17595e 100644
--- a/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/p8_image_help.C
+++ b/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/p8_image_help.C
@@ -38,6 +38,8 @@
/*------------------------------------------------------------------------------*/
#include "p8_delta_scan_rw.h"
+#include "p8_pore_table_gen_api.H"
+#include "common_scom_addresses.H"
#ifdef __FAPI
#include <fapi.H>
@@ -47,9 +49,9 @@ extern "C" {
// get_ring_layout_from_image()
//
-int get_ring_layout_from_image( const void *i_imageIn,
+int get_ring_layout_from_image( const void *i_imageIn,
uint32_t i_ddLevel,
- uint8_t i_sysPhase,
+ uint8_t i_sysPhase,
DeltaRingLayout *o_rs4RingLayout,
void **nextRing)
{
@@ -158,28 +160,31 @@ int get_ring_layout_from_image( const void *i_imageIn,
sizeof(thisRingLayout->reserved2));
o_rs4RingLayout->rs4Launch = (uint32_t*)((uintptr_t)thisRingLayout +
myRev64(thisRingLayout->entryOffset));
- // Since RS4 launch size is only word-aligned, make sure to point to nearest [higher] double-word boundary.
- o_rs4RingLayout->rs4Delta = (uint32_t*)((((uintptr_t)thisRingLayout +
+ // entryOffset, rs4Launch and ASM_RS4_LAUNCH_BUF_SIZE should already be 8-byte aligned.
+ o_rs4RingLayout->rs4Delta = (uint32_t*)( (uintptr_t)thisRingLayout +
myRev64(thisRingLayout->entryOffset) +
- ASM_RS4_LAUNCH_BUF_SIZE-1)/8+1)*8);
-
- // Check that the ring layout structure in the memory is double-word aligned. This must be so because:
- // - The entryOffset address must be on an 8-byte boundary because the start of the .initf ELF section must
- // be 8-byte aligned AND because the rs4Delta member is the last member and which must itself be 8-byte aligned.
- // - These two things together means that both the beginning and end of the delta ring layout must be 8-byte
- // aligned, and thus the whole block,i.e. sizeOfThis, must be 8-byte aligned.
- // Also check that the RS4 delta ring is double-word aligned.
- // Also check that the RS4 launcher is word aligned.
+ ASM_RS4_LAUNCH_BUF_SIZE );
+
+ // Check that the ring layout structure in the memory is 8-byte aligned. This must
+ // be so because:
+ // - The entryOffset address must be on an 8-byte boundary because the start of the
+ // .rings section must be 8-byte aligned AND because the rs4Delta member is the
+ // last member and which must itself be 8-byte aligned.
+ // - These two things together means that both the beginning and end of the delta
+ // ring layout must be 8-byte aligned, and thus the whole block, i.e. sizeOfThis,
+ // must therefore automatically be 8-byte aligned.
+ // Also check that the RS4 delta ring is 8-byte aligned.
+ // Also check that the RS4 launcher is 8-byte aligned.
//
if (((uintptr_t)thisRingLayout-(uintptr_t)i_imageIn)%8 ||
myRev32(o_rs4RingLayout->sizeOfThis)%8 ||
- (uintptr_t)o_rs4RingLayout->rs4Launch%4 ||
- (uintptr_t)o_rs4RingLayout->rs4Delta%8) {
- MY_ERR("ERROR : Ring layout is not double-word-aligned or RS4 launcher is not word aligned.");
- MY_ERR(" thisRingLayout#8 = 0x%016llx",(uint64_t)thisRingLayout%8);
- MY_ERR(" myRev32(o_rs4RingLayout->sizeOfThis)#8 = %i",myRev32(o_rs4RingLayout->sizeOfThis)%8);
- MY_ERR(" o_rs4RingLayout->rs4Launch#4 = 0x%016llx",(uint64_t)o_rs4RingLayout->rs4Launch%4);
- MY_ERR(" o_rs4RingLayout->rs4Delta#8 = 0x%016llx",(uint64_t)o_rs4RingLayout->rs4Delta%8);
+ myRev64(o_rs4RingLayout->entryOffset)%8 ||
+ ASM_RS4_LAUNCH_BUF_SIZE%8) {
+ MY_ERR("ERROR : Ring block or layout structure is not 8-byte aligned:");
+ MY_ERR(" thisRingLayout-imageIn = %i",(uintptr_t)thisRingLayout-(uintptr_t)i_imageIn);
+ MY_ERR(" o_rs4RingLayout->sizeOfThis = %i",myRev32(o_rs4RingLayout->sizeOfThis));
+ MY_ERR(" o_rs4RingLayout->entryOffset = %i",(uint32_t)myRev64(o_rs4RingLayout->entryOffset));
+ MY_ERR(" ASM_RS4_LAUNCH_BUF_SIZE = %i",(uint32_t)ASM_RS4_LAUNCH_BUF_SIZE);
return IMGBUILD_ERR_MISALIGNED_RING_LAYOUT;
}
@@ -197,16 +202,17 @@ int get_ring_layout_from_image( const void *i_imageIn,
// create_wiggle_flip_prg() function
// Notes:
-// - WF procedure needs to be updated with polling protocol.
-// - WF procedure needs to reflect P0/P1 usage policy
-int create_wiggle_flip_prg( uint32_t *i_deltaRing, // scan ring delta state
+// - WF routine implements dynamic P1 multicast bit set based on P0 status.
+// - WF routine checks header word on scan complete.
+// - WF routine is 8-byte aligned.
+int create_wiggle_flip_prg( uint32_t *i_deltaRing, // scan ring delta state (in BE format)
uint32_t i_ringBitLen, // length of ring
uint32_t i_scanSelectData, // Scan ring modifier data
uint32_t i_chipletID, // Chiplet ID
uint32_t **o_wfInline, // location of the PORE instructions data stream
uint32_t *o_wfInlineLenInWords) // final length of data stream
{
- uint32_t rc=P8_PORE_SUCCESS_RC; //defined in p8_pore_api_const.h
+ uint32_t rc=0; //defined in p8_pore_api_const.h
uint32_t i=0;
uint32_t scanSelectAddr=0;
uint32_t scanRing_baseAddr=0;
@@ -214,16 +220,21 @@ int create_wiggle_flip_prg( uint32_t *i_deltaRing, // scan ring delta s
uint32_t scanRingCheckWord=0;
uint32_t count=0;
uint32_t rotateLen=0, remainder=0, remainingBits=0;
- uint32_t osIndex=0;
int pgas_rc=0;
uint64_t pore_imm64b=0;
uint32_t maxWfInlineLenInWords = 10*MAX_RING_SIZE/32;
PoreInlineContext ctx;
- PoreInlineLocation src3=0, tgt3=0;
*o_wfInline = (uint32_t*)malloc(maxWfInlineLenInWords);
- //pore_inline_context_create(&ctx, buf, P8_PORE_BUFSIZE * 4, 0, PORE_INLINE_CHECK_PARITY);
+/* Uncomment to dump ring state
+ printf("\n");
+ for (i=0; i<i_ringBitLen/4; i++) {
+ printf("%02x",*((uint8_t*)i_deltaRing+i));
+ if ((i+1)%32==0) printf("\n");
+ }
+*/
+
pore_inline_context_create(&ctx, *o_wfInline, maxWfInlineLenInWords * 4, 0, 0);
// Get chiplet and Ring Addr info.
@@ -238,34 +249,35 @@ int create_wiggle_flip_prg( uint32_t *i_deltaRing, // scan ring delta s
scanRing_poreAddr=scanRing_baseAddr; // Init scan ring rotate addr
scanRingCheckWord=P8_SCAN_CHECK_WORD; // Header check word for checking ring write was successful
- // Program scanselq reg for scan clock control setup before ring scan
- // --------------------------------------------------------------------------
-
#ifndef SLW_BUILD_WF_P0_FIX
-// The following fix is a direct copy of the setp1_mcreadand macro in ./ipl/sbe/p8_slw.H
+ // This fix is a direct copy of the setp1_mcreadand macro in ./ipl/sbe/p8_slw.H
uint64_t CLEAR_MC_TYPE_MASK=0x47;
PoreInlineLocation src1=0, src2=0, tgt1=0, tgt2=0;
- pgas_rc = pore_MR( &ctx, D1, P0) ||
- pore_ANDI( &ctx, D1, D1, BIT(57)) ||
- PORE_LOCATION( &ctx, src1) ||
- pore_BRANZ( &ctx, D1, src1) ||
- pore_MR( &ctx, P1, P0) ||
- PORE_LOCATION( &ctx, src2) ||
- pore_BRA( &ctx, tgt2) ||
- PORE_LOCATION( &ctx, tgt1) ||
- pore_MR( &ctx, D1, P0) ||
- pore_ANDI( &ctx, D1, D1, CLEAR_MC_TYPE_MASK) ||
- pore_ORI( &ctx, D1, D1, BIT(60)) ||
- pore_MR( &ctx, P1, D1) ||
- PORE_LOCATION( &ctx, tgt2);
+ pgas_rc = pore_MR( &ctx, D1, P0);
+ pgas_rc = pgas_rc + pore_ANDI( &ctx, D1, D1, BIT(57));
+ pgas_rc = pgas_rc + PORE_LOCATION( &ctx, src1);
+ pgas_rc = pgas_rc + pore_BRANZ( &ctx, D1, src1);
+ pgas_rc = pgas_rc + pore_MR( &ctx, P1, P0);
+ pgas_rc = pgas_rc + PORE_LOCATION( &ctx, src2);
+ pgas_rc = pgas_rc + pore_BRA( &ctx, tgt2);
+ pgas_rc = pgas_rc + PORE_LOCATION( &ctx, tgt1);
+ pgas_rc = pgas_rc + pore_MR( &ctx, D1, P0);
+ pgas_rc = pgas_rc + pore_ANDI( &ctx, D1, D1, CLEAR_MC_TYPE_MASK);
+ pgas_rc = pgas_rc + pore_ORI( &ctx, D1, D1, BIT(60));
+ pgas_rc = pgas_rc + pore_MR( &ctx, P1, D1);
+ pgas_rc = pgas_rc + PORE_LOCATION( &ctx, tgt2);
if (pgas_rc>0) {
MY_ERR("***setp1_mcreadand rc = %d", pgas_rc);
return pgas_rc;
}
- pgas_rc = pore_inline_branch_fixup( &ctx, src1, tgt1) ||
- pore_inline_branch_fixup( &ctx, src2, tgt2);
+ pgas_rc = pore_inline_branch_fixup( &ctx, src1, tgt1);
if (pgas_rc>0) {
- MY_ERR("***inline_branch_fixup rc = %d", pgas_rc);
+ MY_ERR("***inline_branch_fixup error (1) rc = %d", pgas_rc);
+ return pgas_rc;
+ }
+ pgas_rc = pore_inline_branch_fixup( &ctx, src2, tgt2);
+ if (pgas_rc>0) {
+ MY_ERR("***inline_branch_fixup error (2) rc = %d", pgas_rc);
return pgas_rc;
}
#else
@@ -277,6 +289,7 @@ int create_wiggle_flip_prg( uint32_t *i_deltaRing, // scan ring delta s
}
#endif
+ // Program scanselq reg for scan clock control setup before ring scan
pore_imm64b = ((uint64_t)i_scanSelectData) << 32;
pgas_rc = pore_STI(&ctx, scanSelectAddr, P0, pore_imm64b);
if (pgas_rc>0) {
@@ -345,7 +358,7 @@ int create_wiggle_flip_prg( uint32_t *i_deltaRing, // scan ring delta s
MY_DBG("base addr = 0x8%x, pore addr = 0x8%x, rotatelen = %d", scanRing_baseAddr, scanRing_poreAddr, rotateLen);
//SCR1RD: shift out then read
- pgas_rc=pore_LD(&ctx, D0, scanRing_poreAddr, P0);
+ pgas_rc=pore_LD(&ctx, D0, scanRing_poreAddr, P1);
if (pgas_rc > 0) {
MY_ERR("***LD D0 rc = %d", pgas_rc);
return pgas_rc;
@@ -359,9 +372,7 @@ int create_wiggle_flip_prg( uint32_t *i_deltaRing, // scan ring delta s
else
scanRing_poreAddr = scanRing_baseAddr | remainingBits;
- //LI : Load XORed value to Scratch 1 reg. (same as p7+)
- //TODO: Check why not overwrite with init values?
- pore_imm64b = ((uint64_t)i_deltaRing[i]) << 32;
+ pore_imm64b = ((uint64_t)myRev32(i_deltaRing[i])) << 32;
pgas_rc = pore_LI(&ctx, D0, pore_imm64b );
if (pgas_rc > 0) {
@@ -396,7 +407,7 @@ int create_wiggle_flip_prg( uint32_t *i_deltaRing, // scan ring delta s
// Rotate the chain and reset rotate length counter
if (rotateLen>0xFC0) {
scanRing_poreAddr = scanRing_baseAddr | rotateLen;
- pgas_rc = pore_LD(&ctx, D0, scanRing_poreAddr, P0);
+ pgas_rc = pore_LD(&ctx, D0, scanRing_poreAddr, P1);
if (pgas_rc > 0) {
MY_ERR("***LD D0 rc = %d", pgas_rc);
return pgas_rc;
@@ -418,7 +429,7 @@ int create_wiggle_flip_prg( uint32_t *i_deltaRing, // scan ring delta s
// shift the ring by remaining shift bit length
if (rotateLen>0) {
scanRing_poreAddr=scanRing_baseAddr | rotateLen;
- pgas_rc = pore_LD(&ctx, D0, scanRing_poreAddr, P0);
+ pgas_rc = pore_LD(&ctx, D0, scanRing_poreAddr, P1);
if (pgas_rc > 0) {
MY_ERR("***LD D0 rc = %d", pgas_rc);
return pgas_rc;
@@ -427,32 +438,123 @@ int create_wiggle_flip_prg( uint32_t *i_deltaRing, // scan ring delta s
}
// Finally, check that our header check word went through in one piece.
+ // Note, we first do the MC-READ-AND check, then the MC-READ-OR check
+#ifndef SLW_BUILD_WF_P0_FIX
+ //
+ // ...First, do the MC-READ-AND check
+ // (Reference: setp1_mcreadand macro in ./ipl/sbe/p8_slw.H)
//
+ PoreInlineLocation src3=0, src5=0, src7=0, src8=0, tgt3=0, tgt5=0, tgt7=0, tgt8=0;
+ pgas_rc = pore_MR( &ctx, D1, P0);
+ pgas_rc = pgas_rc + pore_ANDI( &ctx, D1, D1, BIT(57));
+ pgas_rc = pgas_rc + PORE_LOCATION( &ctx, src3);
+ pgas_rc = pgas_rc + pore_BRANZ( &ctx, D1, src3);
+ pgas_rc = pgas_rc + pore_MR( &ctx, P1, P0); // If here, MC=0. Omit MC check in OR case.
+ pgas_rc = pgas_rc + PORE_LOCATION( &ctx, src7);
+ pgas_rc = pgas_rc + pore_BRA( &ctx, tgt7);
+ pgas_rc = pgas_rc + PORE_LOCATION( &ctx, tgt3);
+ pgas_rc = pgas_rc + pore_MR( &ctx, D1, P0);
+ pgas_rc = pgas_rc + pore_ANDI( &ctx, D1, D1, CLEAR_MC_TYPE_MASK);
+ pgas_rc = pgas_rc + pore_ORI( &ctx, D1, D1, BIT(60));
+ pgas_rc = pgas_rc + pore_MR( &ctx, P1, D1);
+ if (pgas_rc>0) {
+ MY_ERR("***setp1_mcreadand rc = %d", pgas_rc);
+ return pgas_rc;
+ }
+ pgas_rc = pore_inline_branch_fixup( &ctx, src3, tgt3);
+ if (pgas_rc>0) {
+ MY_ERR("***inline_branch_fixup error (3) rc = %d", pgas_rc);
+ return pgas_rc;
+ }
+ // ...Load the output check word...
+ pgas_rc = pore_LD(&ctx, D0, scanRing_baseAddr, P1);
+ // Compare against the reference header check word...
+ pgas_rc = pgas_rc + pore_XORI( &ctx, D0, D0, ((uint64_t)scanRingCheckWord) << 32);
+ pgas_rc = pgas_rc + PORE_LOCATION( &ctx, src5);
+ pgas_rc = pgas_rc + pore_BRAZ( &ctx, D0, tgt5);
+ pgas_rc = pgas_rc + pore_HALT( &ctx);
+ pgas_rc = pgas_rc + PORE_LOCATION( &ctx, tgt5);
+ if (pgas_rc > 0) {
+ MY_ERR("***LD, XORI, BRANZ, RET or HALT went wrong rc = %d", pgas_rc);
+ return pgas_rc;
+ }
+ pgas_rc = pore_inline_branch_fixup( &ctx, src5, tgt5);
+ if (pgas_rc>0) {
+ MY_ERR("***inline_branch_fixup error (5) rc = %d", pgas_rc);
+ return pgas_rc;
+ }
+ //
+ // ...Now do the MC-READ-OR check
+ // (Reference: setp1_mcreador macro in ./ipl/sbe/p8_slw.H)
+ // Note. If we made is this far, we know that MC=1 already, so don't check for it.
+ //
+ pgas_rc = pore_MR( &ctx, D1, P0);
+ pgas_rc = pgas_rc + pore_ANDI( &ctx, D1, D1, CLEAR_MC_TYPE_MASK); // This also clears bit-60.
+ pgas_rc = pgas_rc + pore_MR( &ctx, P1, D1);
+ pgas_rc = pgas_rc + PORE_LOCATION( &ctx, tgt7);
+ if (pgas_rc>0) {
+ MY_ERR("***setp1_mcreadand rc = %d", pgas_rc);
+ return pgas_rc;
+ }
+ pgas_rc = pore_inline_branch_fixup( &ctx, src7, tgt7);
+ if (pgas_rc>0) {
+ MY_ERR("***inline_branch_fixup error (7) rc = %d", pgas_rc);
+ return pgas_rc;
+ }
+ // ...Load the output check word...
+ pgas_rc = pore_LD(&ctx, D0, scanRing_baseAddr, P1);
+ pgas_rc = pgas_rc + pore_XORI( &ctx, D0, D0, ((uint64_t)scanRingCheckWord) << 32);
+ pgas_rc = pgas_rc + PORE_LOCATION( &ctx, src8);
+ pgas_rc = pgas_rc + pore_BRAZ( &ctx, D0, tgt8);
+ pgas_rc = pgas_rc + pore_HALT( &ctx);
+ pgas_rc = pgas_rc + PORE_LOCATION( &ctx, tgt8);
+ pgas_rc = pgas_rc + pore_LI( &ctx, D0, 0x0); // Do shadowing by setpulse.
+ pgas_rc = pgas_rc + pore_STD( &ctx, D0, GENERIC_CLK_SCAN_UPDATEDR_0x0003A000, P0);
+ pgas_rc = pgas_rc + pore_RET( &ctx);
+ if (pgas_rc > 0) {
+ MY_ERR("***LD, XORI, BRANZ, RET or HALT went wrong rc = %d", pgas_rc);
+ return pgas_rc;
+ }
+ pgas_rc = pore_inline_branch_fixup( &ctx, src8, tgt8);
+ if (pgas_rc>0) {
+ MY_ERR("***inline_branch_fixup error (8) rc = %d", pgas_rc);
+ return pgas_rc;
+ }
+#else
+ PoreInlineLocation src3=0, tgt3=0;
// Load the output check word...
- pgas_rc = pore_LD(&ctx, D0, scanRing_baseAddr, P0) |
+ pgas_rc = pore_LD(&ctx, D0, scanRing_baseAddr, P1);
// Compare against the reference header check word...
- pore_XORI( &ctx, D0, D0, ((uint64_t)scanRingCheckWord) << 32) |
- // For now, branch to HALT instruction if not equal, otherwise return in the following instruction...
- // But eventually branch to firmware error_handler if not equal
- // pore_BRANZ(&ctx, D0, error_handler) ||
- PORE_LOCATION( &ctx, src3) |
-// pore_BRANZ( &ctx, D0, ctx.lc+8) || // Jump two 4-byte instr (incl this one) to get to HALT.
- pore_BRANZ( &ctx, D0, tgt3) | // Jump two 4-byte instr (incl this one) to get to HALT.
- pore_RET( &ctx) |
- PORE_LOCATION( &ctx, tgt3) |
- pore_HALT( &ctx);
+ pgas_rc = pgas_rc + pore_XORI( &ctx, D0, D0, ((uint64_t)scanRingCheckWord) << 32);
+ pgas_rc = pgas_rc + PORE_LOCATION( &ctx, src3);
+ // For now, branch to HALT instruction if NZ, otherwise return in the following instr ..eventually branch to firmware error_handler i.e. pore_BRANZ(&ctx, D0, error_handler)
+ pgas_rc = pgas_rc + pore_BRANZ( &ctx, D0, tgt3); //pore_BRANZ( &ctx, D0, ctx.lc+8)
+ pgas_rc = pgas_rc + pore_RET( &ctx);
+ pgas_rc = pgas_rc + PORE_LOCATION( &ctx, tgt3);
+ pgas_rc = pgas_rc + pore_HALT( &ctx);
if (pgas_rc > 0) {
MY_ERR("***LD, XORI, BRANZ, RET or HALT went wrong rc = %d", pgas_rc);
return pgas_rc;
}
pgas_rc = pore_inline_branch_fixup( &ctx, src3, tgt3);
if (pgas_rc>0) {
- MY_ERR("***inline_branch_fixup rc = %d", pgas_rc);
+ MY_ERR("***inline_branch_fixup error (3) rc = %d", pgas_rc);
return pgas_rc;
}
+#endif
- osIndex = ctx.lc/4;
- *o_wfInlineLenInWords = osIndex;
+ *o_wfInlineLenInWords = ctx.lc/4;
+
+ // 8-byte align code, just as a precaution.
+ if ((*o_wfInlineLenInWords*4)%8) {
+ // Insert 4-byte NOP at end.
+ pgas_rc = pore_NOP( &ctx);
+ if (pgas_rc>0) {
+ MY_ERR("***NOP went wrong rc = %d", pgas_rc);
+ return pgas_rc;
+ }
+ *o_wfInlineLenInWords = ctx.lc/4;
+ }
return rc;
}
@@ -460,51 +562,47 @@ int create_wiggle_flip_prg( uint32_t *i_deltaRing, // scan ring delta s
// write_wiggle_flip_to_image()
-// 1 - mmap input image,
-// 2 - Compose delta binary buffer containing RS4 launcher + RS4 delta data,
-// 3 - Append delta buffer to .initf section.
-// 4 - Save new image to output image file.
-int write_wiggle_flip_to_image( void *io_imageOut,
+int write_wiggle_flip_to_image( void *io_imageOut,
uint32_t *i_sizeImageMaxNew,
DeltaRingLayout *i_ringLayout,
uint32_t *i_wfInline,
uint32_t i_wfInlineLenInWords)
{
uint32_t rc=0, bufLC;
+ int deltaLC, i;
uint32_t sizeImageIn, sizeNewDataBlock;
uint32_t sizeImageOutThisEst=0, sizeImageOutThis=0;
- void *initfBuffer=NULL;
+ void *ringsBuffer=NULL;
uint32_t ringRingsOffset=0;
uint64_t ringPoreAddress=0,backPtr=0,fwdPtr=0,fwdPtrCheck;
- SBE_XIP_ERROR_STRINGS(errorStrings);
+ SBE_XIP_ERROR_STRINGS(errorStrings);
MY_DBG("wfInlineLenInWords=%i", i_wfInlineLenInWords);
// Modify the input ring layout content
- // - Remove the qualifier section: ddLevel, sysPhase, override and reserved1+2. This means
- // reducing the entryOffset by the size of these qualifiers.
- // - Adjust sizeOfThis
- // - Use new wfInline member of ring layout struct.
- // - Ignore the rs4Delta member
- //
- // For sizeOfThis, we must ensure 4-byte alignment WF code. That is easy since both entryOffset
- // and wfInlineLenInWord are already word-aligned.
+ // - Remove the qualifier section: ddLevel, sysPhase, override and reserved1+2.
+ // This means reducing the entryOffset by the size of these qualifiers.
+ // - The new WF ring block and start of WF code must both be 8-byte aligned.
+ // - RS4 entryOffset is already 8-byte aligned.
+ // - The WF code section, i.e. wfInlineLenInWords, is already 8-byte aligned.
//
- i_ringLayout->entryOffset = myRev64( myRev64(i_ringLayout->entryOffset) -
- sizeof(i_ringLayout->ddLevel) -
- sizeof(i_ringLayout->sysPhase) -
- sizeof(i_ringLayout->override) -
- sizeof(i_ringLayout->reserved1) -
- sizeof(i_ringLayout->reserved2) );
- i_ringLayout->sizeOfThis = myRev32( myRev64(i_ringLayout->entryOffset) +
- i_wfInlineLenInWords*4 );
+ i_ringLayout->entryOffset =
+ myRev64( myByteAlign(8, myRev64(i_ringLayout->entryOffset) -
+ sizeof(i_ringLayout->ddLevel) -
+ sizeof(i_ringLayout->sysPhase) -
+ sizeof(i_ringLayout->override) -
+ sizeof(i_ringLayout->reserved1) -
+ sizeof(i_ringLayout->reserved2) ) );
+ i_ringLayout->sizeOfThis =
+ myRev32( myRev64(i_ringLayout->entryOffset) + i_wfInlineLenInWords*4 );
+
// Not really any need for this. Just being consistent. Once we have transitioned completely to new
// headers, then ditch i_wfInline from parm list and assign wfInline to layout in main program.
i_ringLayout->wfInline = i_wfInline;
- if (((uintptr_t)i_ringLayout)%4 || myRev64(i_ringLayout->entryOffset)%4) {
- MY_ERR("ERROR : Ring layout is not word-aligned.");
+ if (myRev64(i_ringLayout->entryOffset)%8 || myRev32(i_ringLayout->sizeOfThis)%8) {
+ MY_ERR("ERROR : Ring block or WF code origin not 8-byte aligned.");
return IMGBUILD_ERR_MISALIGNED_RING_LAYOUT;
}
@@ -517,63 +615,82 @@ int write_wiggle_flip_to_image( void *io_imageOut,
}
sizeNewDataBlock = myRev32(i_ringLayout->sizeOfThis);
// ...estimate max size of new image
- sizeImageOutThisEst = sizeImageIn + sizeNewDataBlock + SBE_XIP_MAX_SECTION_ALIGNMENT; //
+ sizeImageOutThisEst = sizeImageIn + sizeNewDataBlock + SBE_XIP_MAX_SECTION_ALIGNMENT; //
if (sizeImageOutThisEst>*i_sizeImageMaxNew) {
MY_ERR("ERROR : Estimated new image size (=%i) would exceed max allowed size (=%i).",
sizeImageOutThisEst, *i_sizeImageMaxNew);
- *i_sizeImageMaxNew = sizeImageOutThisEst;
+ *i_sizeImageMaxNew = sizeImageOutThisEst;
return IMGBUILD_ERR_IMAGE_TOO_LARGE;
}
- MY_DBG("Input image size\t\t= %6i\n\tNew initf data block size\t= %6i\n\tOutput image size\t\t<=%6i",
+ MY_DBG("Input image size\t\t= %6i\n\tNew rings data block size\t= %6i\n\tOutput image size (max)\t\t<=%6i",
sizeImageIn, sizeNewDataBlock, sizeImageOutThisEst);
MY_DBG("entryOffset = %i\n\tsizeOfThis = %i\n\tMeta data size = %i",
(uint32_t)myRev64(i_ringLayout->entryOffset), myRev32(i_ringLayout->sizeOfThis), myRev32(i_ringLayout->sizeOfMeta));
MY_DBG("Back item ptr = 0x%016llx",myRev64(i_ringLayout->backItemPtr));
- MY_DBG("DD level = %i\n\tSys phase = %i\n\tOverride = %i\n\tReserved1+2 = %i",
+ MY_DBG("DD level = 0x%02x\n\tSys phase = %i\n\tOverride = %i\n\tReserved1+2 = %i",
myRev32(i_ringLayout->ddLevel), i_ringLayout->sysPhase, i_ringLayout->override, i_ringLayout->reserved1|i_ringLayout->reserved2);
- // Combine rs4RingLayout members into a unified buffer (initfBuffer).
+ // Combine rs4RingLayout members into a unified buffer (ringsBuffer).
//
- initfBuffer = malloc((size_t)sizeNewDataBlock);
- if (initfBuffer == NULL) {
+ ringsBuffer = malloc((size_t)sizeNewDataBlock);
+ if (ringsBuffer == NULL) {
MY_ERR("ERROR : malloc() of initf buffer failed.");
return IMGBUILD_ERR_MEMORY;
}
- // ... and copy the WF ring layout content into initfBuffer in BIG-ENDIAN format.
+ // ... First, copy WF ring layout header into ringsBuffer in BIG-ENDIAN format.
bufLC = 0;
- memcpy( (uint8_t*)initfBuffer+bufLC, &i_ringLayout->entryOffset, (uintptr_t)&i_ringLayout->metaData-(uintptr_t)&i_ringLayout->entryOffset);
- bufLC = (uintptr_t)&i_ringLayout->metaData-(uintptr_t)&i_ringLayout->entryOffset;
- memcpy( (uint8_t*)initfBuffer+bufLC, i_ringLayout->metaData, myRev32(i_ringLayout->sizeOfMeta));
-
- bufLC = (uint32_t)myRev64(i_ringLayout->entryOffset);
- // The above forces word-alignment of bufLC as [previous] metaData member is only byte aligned.
- memcpy( (uint8_t*)initfBuffer+bufLC, i_wfInline, i_wfInlineLenInWords*4);
+ deltaLC = (uintptr_t)&i_ringLayout->ddLevel-(uintptr_t)&i_ringLayout->entryOffset;
+ memcpy( (uint8_t*)ringsBuffer+bufLC, &i_ringLayout->entryOffset, deltaLC);
+ // ... then meta data
+ bufLC = bufLC + deltaLC;
+ deltaLC = myRev32(i_ringLayout->sizeOfMeta);
+ memcpy( (uint8_t*)ringsBuffer+bufLC, i_ringLayout->metaData, deltaLC);
+ // ... Is this padding or WF buffer?
+ bufLC = bufLC + deltaLC;
+ deltaLC = (uint32_t)myRev64(i_ringLayout->entryOffset) - bufLC;
+ if (deltaLC<0 || deltaLC>=8) {
+ MY_ERR("ERROR : Ring layout mess. Check code or delta_scan(). deltaLC=%i",deltaLC);
+ return IMGBUILD_ERR_CHECK_CODE;
+ }
+ if (deltaLC>0) {
+ // OK, it's padding time.
+ for (i=0; i<deltaLC; i++)
+ *(uint8_t*)((uint8_t*)ringsBuffer+bufLC+i) = 0;
+ }
+ // ... now do the WF buffer
+ bufLC = bufLC + deltaLC;
+ if (bufLC!=(uint32_t)myRev64(i_ringLayout->entryOffset)) {
+ MY_ERR("ERROR : Ring layout messup. Check code or delta_scan().");
+ return IMGBUILD_ERR_CHECK_CODE;
+ }
+ deltaLC = i_wfInlineLenInWords*4;
+ memcpy( (uint8_t*)ringsBuffer+bufLC, i_wfInline, deltaLC);
// Append WF ring layout to .rings section of in-memory input image.
- // Note! All layout members should already be 4-byte-aligned.
+ // Note! All layout members should already be 8-byte aligned.
//
rc = sbe_xip_append( io_imageOut,
SBE_XIP_SECTION_RINGS,
- (void*)initfBuffer,
+ (void*)ringsBuffer,
sizeNewDataBlock,
sizeImageOutThisEst,
&ringRingsOffset);
MY_DBG("ringRingsOffset=0x%08x",ringRingsOffset);
if (rc) {
MY_ERR("ERROR : sbe_xip_append() failed: %s", SBE_XIP_ERROR_STRING(errorStrings, rc));
- if (initfBuffer) free(initfBuffer);
+ if (ringsBuffer) free(ringsBuffer);
return IMGBUILD_ERR_XIP_MISC;
}
// ...get new image size, update return size, and test if successful update.
sbe_xip_image_size( io_imageOut, &sizeImageOutThis);
MY_DBG("Output image size (final)\t=%i",sizeImageOutThis);
- *i_sizeImageMaxNew = sizeImageOutThis;
+ *i_sizeImageMaxNew = sizeImageOutThis;
rc = sbe_xip_validate( io_imageOut, sizeImageOutThis);
if (rc) {
MY_ERR("ERROR : sbe_xip_validate() of output image failed: %s", SBE_XIP_ERROR_STRING(errorStrings, rc));
- if (initfBuffer) free(initfBuffer);
+ if (ringsBuffer) free(ringsBuffer);
return IMGBUILD_ERR_XIP_MISC;
}
MY_DBG("Successful append of RS4 ring to .rings. Next, update forward ptr...");
@@ -586,7 +703,7 @@ int write_wiggle_flip_to_image( void *io_imageOut,
MY_DBG("fwdPtr=0x%016llx", fwdPtr);
if (rc) {
MY_ERR("ERROR : sbe_xip_section2pore() failed: %s", SBE_XIP_ERROR_STRING(errorStrings, rc));
- if (initfBuffer) free(initfBuffer);
+ if (ringsBuffer) free(ringsBuffer);
return IMGBUILD_ERR_XIP_MISC;
}
// ...then update the forward pointer, i.e. the old "variable/ring name's" pointer.
@@ -603,7 +720,7 @@ int write_wiggle_flip_to_image( void *io_imageOut,
&fwdPtrCheck);
if (rc) {
MY_ERR("ERROR : sbe_xip_[write,read]_uint64() failed: %s", SBE_XIP_ERROR_STRING(errorStrings, rc));
- if (initfBuffer) free(initfBuffer);
+ if (ringsBuffer) free(ringsBuffer);
return IMGBUILD_ERR_XIP_MISC;
}
if (fwdPtrCheck!=ringPoreAddress || backPtr!=myRev64(i_ringLayout->backItemPtr)) {
@@ -612,7 +729,7 @@ int write_wiggle_flip_to_image( void *io_imageOut,
MY_ERR("fwdPtrCheck =0x%016llx",fwdPtrCheck);
MY_ERR("layout bckPtr=0x%016llx",myRev64(i_ringLayout->backItemPtr));
MY_ERR("backPtr =0x%016llx",backPtr);
- if (initfBuffer) free(initfBuffer);
+ if (ringsBuffer) free(ringsBuffer);
return IMGBUILD_ERR_FWD_BACK_PTR_MESS;
}
// ...test if successful update.
@@ -622,11 +739,11 @@ int write_wiggle_flip_to_image( void *io_imageOut,
MY_ERR("Probable cause:");
MY_ERR("\tsbe_xip_write_uint64() updated at the wrong address (=0x%016llx)",
myRev64(i_ringLayout->backItemPtr));
- if (initfBuffer) free(initfBuffer);
+ if (ringsBuffer) free(ringsBuffer);
return IMGBUILD_ERR_XIP_MISC;
}
- if (initfBuffer) free(initfBuffer);
+ if (ringsBuffer) free(ringsBuffer);
return rc;
}
@@ -657,11 +774,11 @@ int append_empty_section( void *io_image,
//
sbe_xip_image_size( io_image, &sizeImageIn);
// ...estimate max size of new image
- sizeImageOutThisEst = sizeImageIn + i_sizeSection + SBE_XIP_MAX_SECTION_ALIGNMENT;
+ sizeImageOutThisEst = sizeImageIn + i_sizeSection + SBE_XIP_MAX_SECTION_ALIGNMENT;
if (sizeImageOutThisEst>*i_sizeImageMaxNew) {
MY_ERR("ERROR : Estimated new image size (=%i) would exceed max allowed size (=%i).",
sizeImageOutThisEst, *i_sizeImageMaxNew);
- *i_sizeImageMaxNew = sizeImageOutThisEst;
+ *i_sizeImageMaxNew = sizeImageOutThisEst;
return IMGBUILD_ERR_IMAGE_TOO_LARGE;
}
@@ -685,7 +802,7 @@ int append_empty_section( void *io_image,
// ...get new image size, update return size, and test if successful update.
sbe_xip_image_size( io_image, &sizeImageOutThis);
MY_DBG("Output image size (final)\t=%i",sizeImageOutThis);
- *i_sizeImageMaxNew = sizeImageOutThis;
+ *i_sizeImageMaxNew = sizeImageOutThis;
rc = sbe_xip_validate( io_image, sizeImageOutThis);
if (rc) {
MY_ERR("ERROR : xip_validate() of output image failed: %s", SBE_XIP_ERROR_STRING(errorStrings, rc));
@@ -701,6 +818,101 @@ int append_empty_section( void *io_image,
+// initialize_slw_section()
+// - allocate space for Ramming and Scomming
+// - populate Scomming table with ret/nop/nop/nop (RNNN) inline asm instructions
+// - update Scomming vector
+int initialize_slw_section( void *io_image,
+ uint32_t *i_sizeImageMaxNew)
+{
+ uint32_t rc=0, i_coreId=0, i_iis=0;
+ int pgas_rc=0;
+ void *bufRNNN=NULL;
+ PoreInlineContext ctx;
+ SbeXipSection xipSection;
+ SbeXipItem xipTocItem;
+ void *hostScomTableFirst, *hostScomTableNext, *hostScomVectorFirst, *hostScomVectorNext;
+ uint64_t xipScomTableFirst;
+
+ SBE_XIP_ERROR_STRINGS(errorStrings);
+
+ rc = 0;
+
+ rc = append_empty_section( io_image,
+ i_sizeImageMaxNew,
+ SBE_XIP_SECTION_SLW,
+ SLW_RAM_TABLE_SIZE + SLW_SCOM_TABLE_SIZE);
+ if (rc)
+ return rc;
+
+ //
+ // Ramming table: Nothing to do. Already 0-initialized in append_empty_section().
+ //
+
+ //
+ // Scomming table: Fill with RNNN (16-byte) instruction sequences.
+ //
+
+ // ... allocate buffer to hold one RNNN instruction sequence.
+ bufRNNN = malloc( XIPSIZE_SCOM_ENTRY);
+
+ // ... create RNNN instruction sequence.
+ pore_inline_context_create( &ctx, bufRNNN, XIPSIZE_SCOM_ENTRY, 0, 0);
+ pgas_rc = pore_RET( &ctx);
+ pgas_rc = pgas_rc + pore_NOP( &ctx);
+ pgas_rc = pgas_rc + pore_NOP( &ctx);
+ pgas_rc = pgas_rc + pore_NOP( &ctx);
+ if (pgas_rc>0) {
+ MY_ERR("***_RET or _NOP generated rc = %d", pgas_rc);
+ if (bufRNNN) free(bufRNNN);
+ return IMGBUILD_ERR_PORE_INLINE_ASM;
+ }
+
+ // ... get host and pore location of Scom table in .slw section.
+ rc = sbe_xip_get_section( io_image, SBE_XIP_SECTION_SLW, &xipSection);
+ if (rc) {
+ MY_ERR("ERROR : sbe_xip_get_section() failed: %s", SBE_XIP_ERROR_STRING(errorStrings, rc));
+ MY_ERR("Probable cause:");
+ MY_ERR("\tThe section (=SBE_XIP_SECTION_SLW=%i) was not found.",SBE_XIP_SECTION_SLW);
+ if (bufRNNN) free(bufRNNN);
+ return IMGBUILD_ERR_KEYWORD_NOT_FOUND;
+ }
+ hostScomTableFirst = (void*)((uintptr_t)io_image + xipSection.iv_offset + SLW_RAM_TABLE_SIZE);
+ sbe_xip_host2pore( io_image, hostScomTableFirst, &xipScomTableFirst);
+
+//#ifdef DUMMY_DEF1 // Undo this ifdef once Scom vector name is defined in TOC.
+ // ... get location of Scom vector from TOC.
+ rc = sbe_xip_find( io_image, SLW_HOST_SCOM_VECTOR_TOC_NAME, &xipTocItem);
+ if (rc) {
+ MY_ERR("ERROR : sbe_xip_find() failed w/rc=%i and %s", rc, SBE_XIP_ERROR_STRING(errorStrings, rc));
+ MY_ERR("Probable cause:");
+ MY_ERR("\tThe keyword (=%s) was not found.",SLW_HOST_SCOM_VECTOR_TOC_NAME);
+ if (bufRNNN) free(bufRNNN);
+ return IMGBUILD_ERR_KEYWORD_NOT_FOUND;
+ }
+ rc = sbe_xip_pore2host( io_image, xipTocItem.iv_address, &hostScomVectorFirst);
+
+ // ... populate entire Scom table with RNNN IIS.
+ for (i_iis=0; i_iis<SLW_SCOM_TABLE_SIZE; i_iis=i_iis+XIPSIZE_SCOM_ENTRY) {
+ hostScomTableNext = (void*)( (uintptr_t)hostScomTableFirst + i_iis);
+ memcpy( hostScomTableNext, bufRNNN, XIPSIZE_SCOM_ENTRY);
+ }
+
+ // ... update Scom vector.
+ for (i_coreId=0; i_coreId<SLW_MAX_CORES; i_coreId++) {
+ hostScomVectorNext = (void*)( (uint64_t*)hostScomVectorFirst + i_coreId);
+ *(uint64_t*)hostScomVectorNext = myRev64( xipScomTableFirst +
+ SLW_SCOM_TABLE_SPACE_PER_CORE*i_coreId);
+ }
+//#endif
+
+ if (bufRNNN) free(bufRNNN);
+
+ return rc;
+}
+
+
+
void cleanup( void *buf1,
void *buf2,
void *buf3,
diff --git a/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/p8_pore_api_const.h b/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/p8_pore_api_const.h
index 43a2a3e5c..1f0f86ada 100644
--- a/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/p8_pore_api_const.h
+++ b/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/p8_pore_api_const.h
@@ -21,23 +21,23 @@
*
* IBM_PROLOG_END_TAG
*/
-/* $Id: p8_pore_api_const.h,v 1.1 2011/08/25 12:32:33 yjkim Exp $ */
+/* $Id: p8_pore_api_const.h,v 1.2 2012/06/11 20:55:00 cmolsen Exp $ */
/* $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/utils/p8_pore_api_const.h,v $ */
/**
* Contains any constants uses as inputs or outputs to the p7p_pore functions
*/
-
+// CMO-20120601: SCOM Operators moved to p8_pore_table_gen_api.H
/****************************/
/***** SCOM Operators *****/
/****************************/
-#define P8_PORE_SCOM_APPEND 0 /* add scom instructions to the end of the existing image */
-#define P8_PORE_SCOM_REPLACE 1 /* replace existing instructions with new data */
-#define P8_PORE_SCOM_OR 2 /* overlay scom data onto existing instruction by bitwise OR */
-#define P8_PORE_SCOM_AND 3 /* overlay scom data onto existing instruction by bitwise AND */
-#define P8_PORE_SCOM_NOOP 4 /* replace existing instructions with NOP */
-#define P8_PORE_SCOM_LAST_OP 4 /* keep track of the last op for checking correctness of op input */
+//#define P8_PORE_SCOM_APPEND 0 /* add scom instructions to the end of the existing image */
+//#define P8_PORE_SCOM_REPLACE 1 /* replace existing instructions with new data */
+//#define P8_PORE_SCOM_OR 2 /* overlay scom data onto existing instruction by bitwise OR */
+//#define P8_PORE_SCOM_AND 3 /* overlay scom data onto existing instruction by bitwise AND */
+//#define P8_PORE_SCOM_NOOP 4 /* replace existing instructions with NOP */
+//#define P8_PORE_SCOM_LAST_OP 4 /* keep track of the last op for checking correctness of op input */
/***************************/
@@ -82,6 +82,10 @@ This section is automatically updated by CVS when you check in this file.
Be sure to create CVS comments when you commit so that they can be included here.
$Log: p8_pore_api_const.h,v $
+Revision 1.2 2012/06/11 20:55:00 cmolsen
+Updated to comment out the Scom operation defines which are now defined in
+p8_pore_table_gen_api.H instead.
+
Revision 1.1 2011/08/25 12:32:33 yjkim
initial checkin
diff --git a/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/p8_pore_table_gen_api.H b/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/p8_pore_table_gen_api.H
deleted file mode 100644
index a99cbc99e..000000000
--- a/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/p8_pore_table_gen_api.H
+++ /dev/null
@@ -1,168 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG
- * This is an automatically generated prolog.
- *
- * $Source: src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/p8_pore_table_gen_api.H $
- *
- * IBM CONFIDENTIAL
- *
- * COPYRIGHT International Business Machines Corp. 2012
- *
- * p1
- *
- * Object Code Only (OCO) source materials
- * Licensed Internal Code Source Materials
- * IBM HostBoot Licensed Internal Code
- *
- * The source code for this program is not published or other-
- * wise divested of its trade secrets, irrespective of what has
- * been deposited with the U.S. Copyright Office.
- *
- * Origin: 30
- *
- * IBM_PROLOG_END_TAG
- */
-/*------------------------------------------------------------------------------*/
-/* *! (C) Copyright International Business Machines Corp. 2012 */
-/* *! All Rights Reserved -- Property of IBM */
-/* *! *** IBM Confidential *** */
-/*------------------------------------------------------------------------------*/
-/* *! TITLE : p8_pore_table_gen_api */
-/* *! DESCRIPTION : Contains all external APIs used by firmware (PHYP) to */
-// generate/modify the P8 PORE SLW image.
-/* *! OWNER NAME : Michael Olsen Email: cmolsen@us.ibm.com */
-/* *! ADDITIONAL COMMENTS : */
-// - Start file: p7p_pore_api.h
-// - _table_entry structs must agree with Greg's proc_slw_ram.H
-//
-/*------------------------------------------------------------------------------*/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-
-#include "pore_bitmanip.H"
-#include "sbe_xip_image.h"
-
-//#ifndef _P8_PORE_API_H
-//#define _P8_PORE_API_H
-
-//#include <p8_pore_api_custom.h>
-//#include <p8_pore_image.h>
-//#include <p8_pore_api_const.h>
-
-/* Common header for *.c and .S ramming code: Call it ../sbe/proc_slw_ram.H ? */
-// Header defs (P8&PORE 64-bit notation where bits are numbered from left-to-right)
-#define RAM_HEADER_END_START 0
-#define RAM_HEADER_END_MASK BITS(RAM_HEADER_END_START,1)
-#define RAM_HEADER_TYPE_START 2
-#define RAM_HEADER_TYPE_MASK BITS(RAM_HEADER_TYPE_START,2)
-#define RAM_HEADER_SPRN_START 4
-#define RAM_HEADER_SPRN_MASK BITS(RAM_HEADER_SPRN_START,10)
-#define RAM_HEADER_THREAD_START 16
-#define RAM_HEADER_THREAD_MASK BITS(RAM_HEADER_THREAD_START,3)
-// MTSPR instr defs
-#define RAM_MTSPR_INSTR_TEMPL ( ( (uint64_t)31<<(63-5) | (uint64_t)467<<(63-30) ) )
-#define RAM_MTSPR_SPR_START 11
-#define RAM_MTSPR_SPR_MASK BITS(RAM_MTSPR_SPR_START,10)
-// Header defs (C notation where bits are numbered from right-to-left, and reducing to 32-bit)
-#define RAM_HEADER_END_START_C ( 31-RAM_HEADER_END_START+1-1 )
-#define RAM_HEADER_END_MASK_C (uint32_t)(RAM_HEADER_END_MASK>>32)
-#define RAM_HEADER_TYPE_START_C ( 31-RAM_HEADER_TYPE_START+1-2 )
-#define RAM_HEADER_TYPE_MASK_C (uint32_t)(RAM_HEADER_TYPE_MASK>>32)
-#define RAM_HEADER_SPRN_START_C ( 31-RAM_HEADER_SPRN_START+1-10 )
-#define RAM_HEADER_SPRN_MASK_C (uint32_t)(RAM_HEADER_SPRN_MASK>>32)
-#define RAM_HEADER_THREAD_START_C ( 31-RAM_HEADER_THREAD_START+1-3 )
-#define RAM_HEADER_THREAD_MASK_C (uint32_t)(RAM_HEADER_THREAD_MASK>>32)
-// MTSPR instr defs
-#define RAM_MTSPR_INSTR_TEMPL_C ( ( (uint32_t)31<<(31-5) | (uint32_t)467<<(31-30) ) )
-#define RAM_MTSPR_SPR_START_C ( 31-RAM_MTSPR_SPR_START+1-10 )
-//#define RAM_MTSPR_SPR_MASK_C (uint32_t)(BITS(RAM_MTSPR_SPR_START,10)>>32)
-#define RAM_MTSPR_SPR_MASK_C (uint32_t)(RAM_MTSPR_SPR_MASK>>32)
-
-/* Other defs needed for ramming */
-// TOC names
-#define SLW_HOST_REG_VECTOR_TOC_NAME "slw_host_reg_vector"
-#define SLW_HOST_SCOM_VECTOR_TOC_NAME "slw_host_scom_vector"
-#define SLW_HOST_REG_TABLE_TOC_NAME "slw_core_reg_table"
-
-// Defines for slw_build() to update "host_runtime_scome" w/pointer to "slw_host_runtime" at SLW image build time.
-#define HOST_RUNTIME_SCOM_TOC_NAME "host_runtime_scom" // Null 1st, then fill w/addr of SLW_HOST_RUNTIME_TOC_NAME
-#define SLW_HOST_RUNTIME_TOC_NAME "slw_host_runtime"
-
-
-// RAM table defines
-#define XIPSIZE_RAM_ENTRY ( (sizeof(RamTableEntry)+7)/8*8 )
-#define SLW_MAX_CORES 16
-#define SLW_MAX_CPUREGS_CORE 8
-#define SLW_MAX_CPUREGS_THREADS 3
-#define SLW_CORE_THREADS 8
-#define SLW_MAX_CPUREGS_OPS ( SLW_MAX_CPUREGS_CORE + \
- SLW_CORE_THREADS*SLW_MAX_CPUREGS_THREADS )
-#define SLW_SLW_SECTION_SIZE ( SLW_MAX_CORES * SLW_MAX_CPUREGS_OPS * XIPSIZE_RAM_ENTRY )
-
-// Return codes
-#define SLW_RAM_SUCCESS 0
-#define SLW_RAM_HEADERS_NOT_SYNCED 1
-#define SLW_RAM_IMAGE_SIZE_MISMATCH 2
-#define SLW_RAM_TABLE_ENTRY_OVERFLOW 3
-#define SLW_RAM_CODE_ERROR 4
-#define SLW_RAM_INVALID_PARAMETER 5
-#define SLW_RAM_WARNING_TABLE_CONTAMINATION 10
-
-#ifdef __cpluscplus
-extern "C" {
-#endif
-
-typedef struct ram_instr_t {
- uint32_t header;
- uint32_t instr;
- uint64_t data;
-} RamTableEntry;
-
-// SLW supported SPR registers
-typedef struct {
- const char *name;
- uint32_t value;
- uint32_t swizzled;
-} SlwSprRegs;
-
-const SlwSprRegs SLW_SPR_REGS[] = {
- /* name value swizzled */
- // ...core regs
- { "P8_SPR_HRMOR", 313, ( 313>>5 | ( 313&0x1f)<<5 ) },
- { "P8_SPR_HMEER", 337, ( 337>>5 | ( 337&0x1f)<<5 ) },
- { "P8_SPR_PMICR", 852, ( 852>>5 | ( 852&0x1f)<<5 ) },
- { "P8_SPR_PMCR", 884, ( 884>>5 | ( 884&0x1f)<<5 ) },
- { "P8_SPR_HID0", 1008, ( 1008>>5 | (1008&0x1f)<<5 ) },
- { "P8_SPR_HID1", 1009, ( 1009>>5 | (1009&0x1f)<<5 ) },
- { "P8_SPR_HID4", 1012, ( 1012>>5 | (1012&0x1f)<<5 ) },
- { "P8_SPR_HID5", 1014, ( 1014>>5 | (1014&0x1f)<<5 ) },
- // ...thread regs
- { "P8_SPR_HSPRG0", 304, ( 304>>5 | ( 304&0x1f)<<5 ) },
- { "P8_SPR_LPCR", 318, ( 318>>5 | ( 318&0x1f)<<5 ) },
- // Greg, this is NOT in jbishop's SS. Got it from ur ST. But 1023 is max!
- { "P8_SPR_MSR", 2000, ( 2000>>5 | (2000&0x1f)<<5 ) }
-};
-
-const int SLW_SPR_REGS_SIZE = sizeof(SLW_SPR_REGS)/sizeof(SLW_SPR_REGS[0]);
-
-
-/* Name: p8_pore_gen_cpureg()
- * Description: Populates ramming entries in the .slw section
- * Parameter list: i_image - pointer to SLW mainstore image
- * i_sizeImage - size of SLW mainstore image
- * i_regName - unswizzled SPR register value
- * i_regData - data to write to SPR register
- * i_coreId - the core ID to operate on
- * i_threadId - the thread ID to operate on
- */
-uint32_t p8_pore_gen_cpureg(void *i_image,
- uint32_t i_sizeImage,
- uint32_t i_regName,
- uint64_t i_regData,
- uint32_t i_coreId,
- uint32_t i_threadId);
-
-#ifdef __cpluscplus
-}
-#endif
diff --git a/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/proc_slw_build.C b/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/proc_slw_build.C
index 3744f1fea..af54eb656 100644
--- a/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/proc_slw_build.C
+++ b/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/proc_slw_build.C
@@ -25,32 +25,38 @@
/* *! TITLE : proc_slw_build */
/* *! DESCRIPTION : Extracts and decompresses delta ring states from EPROM */
// image. Utilizes the linked list approach (LLA) to extract
-// and position wiggle-flip programs in .rings according to
-// back pointer, DD level, phase and override settings.
+// and position wiggle-flip programs in .rings according to
+// back pointer, DD level, phase and override settings.
/* *! OWNER NAME : Michael Olsen cmolsen@us.ibm.com */
//
/* *! EXTENDED DESCRIPTION : */
//
/* *! USAGE : To build (for Hostboot) - */
// buildfapiprcd -r ver-12-5 -C "p8_image_help.C,p8_scan_compression.C" -c "sbe_xip_image.c,pore_inline_assembler.c,pore_inline_disassembler.c,p8_pore_static_data.c" -e "../../xml/error_info/proc_slw_build_errors.xml" proc_slw_build.C
-// Parameter list -
+// Parameter list -
// See function definition below.
-// Alternative usages -
-// To build for scanning by EPM team:
-// buildfapiprcd_cmo -u "SLW_BUILD_WF_P0_FIX,SLW_BUILD_SYSPHASE_ZERO_MODE,SLW_COMMAND_LINE" -r ...
+// Alternative usages -
+// To build for scanning by EPM team w/fixed P0 value, sysPhase=0,
+// always-return-after-wf, command-line mode:
+// buildfapiprcd -u "SLW_BUILD_WF_P0_FIX,SLW_BUILD_SYSPHASE_ZERO_MODE,SLW_BUILD_WF_RETURN,SLW_COMMAND_LINE" -r ...
//
/* *! ASSUMPTIONS : */
-// - For proc_slw_build, sysPhase=1 is assumed during real hostboot.
+// - For Hostboot environment:
+// - dynamic P0/P1 calculation
+// - sysPhase=1
+// - check header word after WF
+// - non-command-line mode, FAPI call
//
/* *! COMMENTS : */
// - All image content, incl .initf content and ring layout, is handled
// in BE format. No matter which platform.
-// - A ring may only be requested with the sysPhase=0 or 1. Any other
+// - A ring may only be requested with the sysPhase=0 or 1. Any other
// sysPhase value, incl sysPhase=2, will cause no rings to be found.
//
/*------------------------------------------------------------------------------*/
#include "proc_slw_build.H"
+#include "p8_delta_scan_rw.h"
extern "C" {
@@ -77,7 +83,7 @@ ReturnCode proc_slw_build( const fapi::Target &i_target,
#else
uint8_t sysPhase=1;
#endif
-
+
uint32_t rcLoc=0, rcSearch=0, i, countWF=0;
uint32_t sizeImage=0, sizeImageOutMax, sizeImageTmp, sizeImageOld;
uint8_t *deltaRingDxed=NULL;
@@ -85,13 +91,13 @@ ReturnCode proc_slw_build( const fapi::Target &i_target,
DeltaRingLayout rs4RingLayout;
void *nextRing=NULL;
- uint32_t ringBitLen=0, ringByteLen=0, ringTrailBits=0;
+ uint32_t ringBitLen=0; //ringByteLen=0, ringTrailBits=0;
uint32_t *wfInline=NULL;
uint32_t wfInlineLenInWords;
sizeImageOutMax = *io_sizeImageOut;
-
+
if (sizeImageOutMax<i_sizeImageIn) {
FAPI_ERR("Inp image size (from caller): %i",i_sizeImageIn);
FAPI_ERR("Max image size (from caller): %i",*io_sizeImageOut);
@@ -100,7 +106,7 @@ ReturnCode proc_slw_build( const fapi::Target &i_target,
FAPI_SET_HWP_ERROR(rc, RC_PROC_SLWB_INPUT_IMAGE_SIZE_MESS);
return rc;
}
-
+
// ==========================================================================
// Check and copy image to mainstore and clean it up.
@@ -128,7 +134,7 @@ ReturnCode proc_slw_build( const fapi::Target &i_target,
return rc;
}
FAPI_DBG("Image size (in EPROM): %i",i_sizeImageIn);
-
+
// Second, copy input image to supplied mainstore location.
//
memcpy( i_imageOut, i_imageIn, i_sizeImageIn);
@@ -188,11 +194,11 @@ ReturnCode proc_slw_build( const fapi::Target &i_target,
// ==========================================================================
// Get DD level from FAPI attributes.
// ==========================================================================
- // $$rc = FAPI_ATTR_GET(ATTR_EC, &i_target, l_uint8);
+// rc = FAPI_ATTR_GET(ATTR_EC, &i_target, l_uint8);
rc = FAPI_ATTR_GET_PRIVILEGED(ATTR_EC, &i_target, l_uint8);
ddLevel = (uint32_t)l_uint8;
if (rc) {
- FAPI_ERR("FAPI_ATTR_GET() failed w/rc=%i and ddLevel=0x%02x",(uint32_t)rc,l_uint8);
+ FAPI_ERR("FAPI_ATTR_GET_PRIVILEGED() failed w/rc=%i and ddLevel=0x%02x",(uint32_t)rc,l_uint8);
return rc;
}
@@ -202,7 +208,7 @@ ReturnCode proc_slw_build( const fapi::Target &i_target,
do {
FAPI_DBG("nextRing (at top)=0x%016llx",(uint64_t)nextRing);
-
+
// ==========================================================================
// Get ring layout from image
@@ -214,8 +220,8 @@ ReturnCode proc_slw_build( const fapi::Target &i_target,
&rs4RingLayout,
&nextRing);
rcSearch = rcLoc;
- if (rcSearch!=DSLWB_RING_SEARCH_MATCH &&
- rcSearch!=DSLWB_RING_SEARCH_EXHAUST_MATCH &&
+ if (rcSearch!=DSLWB_RING_SEARCH_MATCH &&
+ rcSearch!=DSLWB_RING_SEARCH_EXHAUST_MATCH &&
rcSearch!=DSLWB_RING_SEARCH_NO_MATCH) {
FAPI_ERR("\tERROR : Getting delta ring from image was unsuccessful (rcSearch=%i).",rcSearch);
FAPI_ERR("\tNo wiggle-flip programs will be stored in .rings section.");
@@ -224,22 +230,20 @@ ReturnCode proc_slw_build( const fapi::Target &i_target,
FAPI_SET_HWP_ERROR(rc, RC_PROC_SLWB_RING_RETRIEVAL_ERROR);
return rc;
}
- if (rcSearch==DSLWB_RING_SEARCH_MATCH ||
+ if (rcSearch==DSLWB_RING_SEARCH_MATCH ||
rcSearch==DSLWB_RING_SEARCH_EXHAUST_MATCH)
FAPI_DBG("\tRetrieving RS4 delta ring was successful.");
// Check if we're done at this point.
- //
+ //
if (rcSearch==DSLWB_RING_SEARCH_NO_MATCH) {
FAPI_INF("Wiggle-flip programming done.");
FAPI_INF("Number of wf programs appended: %i", countWF);
if (countWF==0)
FAPI_INF("ZERO WF programs appended to .rings section.");
sizeImageTmp = sizeImageOutMax;
- rcLoc = append_empty_section( i_imageOut,
- &sizeImageTmp,
- SBE_XIP_SECTION_SLW,
- SLW_SLW_SECTION_SIZE);
+ rcLoc = initialize_slw_section( i_imageOut,
+ &sizeImageTmp);
if (rcLoc) {
if (rcLoc==IMGBUILD_ERR_IMAGE_TOO_LARGE) {
uint32_t & DATA_IMG_SIZE_OLD=sizeImageOld;
@@ -253,14 +257,14 @@ ReturnCode proc_slw_build( const fapi::Target &i_target,
}
return rc;
}
- FAPI_INF("SLW section allocated for Ramming table.");
+ FAPI_INF("SLW section allocated for Ramming and Scomming tables.");
sbe_xip_image_size( i_imageOut, io_sizeImageOut);
FAPI_INF("Final SLW image size: %i", *io_sizeImageOut);
return FAPI_RC_SUCCESS;
}
-
+
deltaRingRS4 = (CompressedScanData*)rs4RingLayout.rs4Delta;
-
+
FAPI_DBG("Dumping ring layout:");
FAPI_DBG("\tentryOffset = %i",(uint32_t)myRev64(rs4RingLayout.entryOffset));
FAPI_DBG("\tbackItemPtr = 0x%016llx",myRev64(rs4RingLayout.backItemPtr));
@@ -270,7 +274,7 @@ ReturnCode proc_slw_build( const fapi::Target &i_target,
FAPI_DBG("\tsysPhase = %i",rs4RingLayout.sysPhase);
FAPI_DBG("\toverride = %i",rs4RingLayout.override);
FAPI_DBG("\treserved1+2 = %i",rs4RingLayout.reserved1|rs4RingLayout.reserved2);
- FAPI_DBG("\tRS4 magic # = 0x%08x",myRev32(deltaRingRS4->iv_magic));
+ FAPI_DBG("\tRS4 magic # = 0x%08x",myRev32(deltaRingRS4->iv_magic));
FAPI_DBG("\tRS4 total size = %i",myRev32(deltaRingRS4->iv_size));
FAPI_DBG("\tUnXed data size = %i",myRev32(deltaRingRS4->iv_length));
FAPI_DBG("\tScan select = 0x%08x",myRev32(deltaRingRS4->iv_scanSelect));
@@ -303,20 +307,20 @@ ReturnCode proc_slw_build( const fapi::Target &i_target,
return rc;
}
FAPI_DBG("\tDecompression successful.\n");
-
- ringByteLen = (ringBitLen-1)/8+1;
- ringTrailBits = ringBitLen - 8*(ringByteLen-1);
+
+// ringByteLen = (ringBitLen-1)/8+1;
+// ringTrailBits = ringBitLen - 8*(ringByteLen-1);
// ==========================================================================
// Create Wiggle-Flip Programs
// ==========================================================================
FAPI_DBG("--> Creating Wiggle-Flip Program.");
- rcLoc = create_wiggle_flip_prg( (uint32_t*)deltaRingDxed,
+ rcLoc = create_wiggle_flip_prg( (uint32_t*)deltaRingDxed,
ringBitLen,
myRev32(deltaRingRS4->iv_scanSelect),
(uint32_t)deltaRingRS4->iv_chipletId,
- &wfInline,
+ &wfInline,
&wfInlineLenInWords);
if (rcLoc) {
FAPI_ERR("ERROR : create_wiggle_flip_prg() failed w/rcLoc=%i",rcLoc);
@@ -327,7 +331,7 @@ ReturnCode proc_slw_build( const fapi::Target &i_target,
return rc;
}
FAPI_DBG("\tWiggle-flip programming successful.");
-
+
// ==========================================================================
// Append Wiggle-Flip programs to .rings section.
@@ -356,7 +360,7 @@ ReturnCode proc_slw_build( const fapi::Target &i_target,
return rc;
}
FAPI_DBG("\tUpdating image w/wiggle-flip program + header was successful.");
-
+
// Update some variables for debugging and error reporting.
sizeImageOld = sizeImageTmp;
countWF++;
@@ -367,8 +371,8 @@ ReturnCode proc_slw_build( const fapi::Target &i_target,
// ==========================================================================
if (deltaRingDxed) free(deltaRingDxed);
if (wfInline) free(wfInline);
-
-
+
+
// ==========================================================================
// Are we done?
// ==========================================================================
@@ -378,10 +382,8 @@ ReturnCode proc_slw_build( const fapi::Target &i_target,
if (countWF==0)
FAPI_INF("ZERO WF programs appended to .rings section.");
sizeImageTmp = sizeImageOutMax;
- rcLoc = append_empty_section( i_imageOut,
- &sizeImageTmp,
- SBE_XIP_SECTION_SLW,
- SLW_SLW_SECTION_SIZE);
+ rcLoc = initialize_slw_section( i_imageOut,
+ &sizeImageTmp);
if (rcLoc) {
if (rcLoc==IMGBUILD_ERR_IMAGE_TOO_LARGE) {
uint32_t & DATA_IMG_SIZE_OLD=sizeImageOld;
@@ -395,14 +397,14 @@ ReturnCode proc_slw_build( const fapi::Target &i_target,
}
return rc;
}
- FAPI_INF("SLW section allocated for Ramming table.");
+ FAPI_INF("SLW section allocated for Ramming and Scomming tables.");
sbe_xip_image_size( i_imageOut, io_sizeImageOut);
FAPI_INF("Final SLW image size: %i", *io_sizeImageOut);
return FAPI_RC_SUCCESS;
}
FAPI_DBG("nextRing (at bottom)=0x%016llx",(uint64_t)nextRing);
-
+
} while (nextRing!=NULL);
/***************************************************************************
* SEARCH LOOP - End *
diff --git a/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/proc_slw_build.H b/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/proc_slw_build.H
index 7db527191..be6d8db06 100644
--- a/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/proc_slw_build.H
+++ b/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/proc_slw_build.H
@@ -23,8 +23,6 @@
*/
#include <fapi.H>
-#include "p8_delta_scan_rw.h"
-#include "p8_pore_table_gen_api.H"
typedef fapi::ReturnCode (*proc_slw_build_FP_t) ( const fapi::Target&,
const void*,
diff --git a/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/proc_slw_build_errors.xml b/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/proc_slw_build_errors.xml
index e579245df..9066290f4 100644
--- a/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/proc_slw_build_errors.xml
+++ b/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/proc_slw_build_errors.xml
@@ -102,7 +102,7 @@
<!-- *********************************************************************** -->
<hwpError>
<rc>RC_PROC_SLWB_UNKOWN_ERROR</rc>
- <description>Unknown error, shouldn't be in this code section.</description>
+ <description>Unknown error. (Shouldn't be in this code section.)</description>
<ffdc>RC_LOCAL</ffdc>
</hwpError>
</hwpErrors>
diff --git a/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/sbe_xip_image.c b/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/sbe_xip_image.c
index 722e8fdb7..138b1d7cb 100644
--- a/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/sbe_xip_image.c
+++ b/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/sbe_xip_image.c
@@ -21,7 +21,7 @@
*
* IBM_PROLOG_END_TAG
*/
-// $Id: sbe_xip_image.c,v 1.17 2012/05/22 22:59:05 bcbrock Exp $
+// $Id: sbe_xip_image.c,v 1.20 2012/06/21 01:41:31 bcbrock Exp $
// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/sbe/sbe_xip_image.c,v $
//-----------------------------------------------------------------------------
// *! (C) Copyright International Business Machines Corp. 2011
@@ -192,6 +192,27 @@ dumpSectionTable(const void* i_image)
// endian-conversion routines rather than counting on a system-specific header
// to provide these.
+/// Byte-reverse a 16-bit integer if on a little-endian machine
+
+static uint16_t
+revle16(const uint16_t i_x)
+{
+ uint16_t rx;
+
+#ifndef _BIG_ENDIAN
+ uint8_t *pix = (uint8_t*)(&i_x);
+ uint8_t *prx = (uint8_t*)(&rx);
+
+ prx[0] = pix[1];
+ prx[1] = pix[0];
+#else
+ rx = i_x;
+#endif
+
+ return rx;
+}
+
+
/// Byte-reverse a 32-bit integer if on a little-endian machine
static uint32_t
@@ -421,8 +442,8 @@ translateSection(SbeXipSection* o_dest, const SbeXipSection* i_src)
{
#ifndef _BIG_ENDIAN
-#if SBE_XIP_HEADER_VERSION != 7
-#error This code assumes the SBE-XIP header version 7 layout
+#if SBE_XIP_HEADER_VERSION != 8
+#error This code assumes the SBE-XIP header version 8 layout
#endif
o_dest->iv_offset = revle32(i_src->iv_offset);
@@ -446,8 +467,8 @@ translateToc(SbeXipToc* o_dest, SbeXipToc* i_src)
{
#ifndef _BIG_ENDIAN
-#if SBE_XIP_HEADER_VERSION != 7
-#error This code assumes the SBE-XIP header version 7 layout
+#if SBE_XIP_HEADER_VERSION != 8
+#error This code assumes the SBE-XIP header version 8 layout
#endif
o_dest->iv_id = revle32(i_src->iv_id);
@@ -476,6 +497,7 @@ finalSection(const void* i_image, int* o_sectionId)
sbe_xip_translate_header(&hostHeader, (SbeXipHeader*)i_image);
offset = 0;
+ *o_sectionId = 0; /* Make GCC -O3 happy */
for (i = 0; i < SBE_XIP_SECTIONS; i++) {
if (hostHeader.iv_section[i].iv_offset > offset) {
*o_sectionId = i;
@@ -835,7 +857,36 @@ validateTocEntry(void* io_image, const SbeXipItem* i_item, void* io_arg)
}
-/// Normalize a TOC entry
+// This is the FNV-1a hash, used for hashing symbol names in the .fixed
+// section into 32-bit hashes for the mini-TOC.
+
+// According to the authors:
+
+// "FNV hash algorithms and source code have been released into the public
+// domain. The authors of the FNV algorithmm look deliberate steps to disclose
+// the algorhtm (sic) in a public forum soon after it was invented. More than
+// a year passed after this public disclosure and the authors deliberatly took
+// no steps to patent the FNV algorithm. Therefore it is safe to say that the
+// FNV authors have no patent claims on the FNV algorithm as published."
+
+#define FNV_OFFSET_BASIS 2166136261u
+#define FNV_PRIME32 16777619u
+
+uint32_t
+hash32(const char* s)
+{
+ uint32_t hash;
+
+ hash = FNV_OFFSET_BASIS;
+ while (*s) {
+ hash ^= *s++;
+ hash *= FNV_PRIME32;
+ }
+ return hash;
+}
+
+
+// Normalize a TOC entry
// Normalize the TOC entry by converting relocatable pointers into 32-bit
// offsets from the beginning of the section containing the data. All
@@ -843,11 +894,14 @@ validateTocEntry(void* io_image, const SbeXipItem* i_item, void* io_arg)
// in bits 16:31 of the link address of the image.
static int
-normalizeToc(void* io_image, SbeXipToc *io_imageToc)
+normalizeToc(void* io_image, SbeXipToc *io_imageToc,
+ SbeXipHashedToc** io_fixedTocEntry,
+ size_t* io_fixedEntriesRemaining)
{
SbeXipToc hostToc;
int idSection, dataSection;
uint32_t idOffset, dataOffset;
+ char* hostString;
int rc;
do {
@@ -858,6 +912,9 @@ normalizeToc(void* io_image, SbeXipToc *io_imageToc)
translateToc(&hostToc, io_imageToc);
+ hostString =
+ (char*)pore2Host(io_image, fullAddress(io_image, hostToc.iv_id));
+
rc = pore2Section(io_image,
fullAddress(io_image, hostToc.iv_id),
&idSection,
@@ -882,6 +939,30 @@ normalizeToc(void* io_image, SbeXipToc *io_imageToc)
hostToc.iv_data = dataOffset;
hostToc.iv_section = dataSection;
+ // If this TOC entry is from .fixed, create a new record in .fixed_toc
+
+ if (hostToc.iv_section == SBE_XIP_SECTION_FIXED) {
+
+ if (*io_fixedEntriesRemaining == 0) {
+ rc = TRACE_ERRORX(SBE_XIP_TOC_ERROR,
+ "Too many TOC entries for .fixed\n");
+ break;
+ }
+ if (hostToc.iv_data != (uint16_t)hostToc.iv_data) {
+ rc = TRACE_ERRORX(SBE_XIP_IMAGE_ERROR,
+ "The .fixed section is too big to index\n");
+ break;
+ }
+
+ (*io_fixedTocEntry)->iv_hash = revle32(hash32(hostString));
+ (*io_fixedTocEntry)->iv_offset = revle16(hostToc.iv_data);
+ (*io_fixedTocEntry)->iv_type = hostToc.iv_type;
+ (*io_fixedTocEntry)->iv_elements = hostToc.iv_elements;
+
+ (*io_fixedTocEntry)++;
+ (*io_fixedEntriesRemaining)--;
+ }
+
// Finally update the TOC entry
translateToc(io_imageToc, &hostToc);
@@ -892,6 +973,33 @@ normalizeToc(void* io_image, SbeXipToc *io_imageToc)
}
+// Check for hash collisions in the .fixed mini-TOC. Note that endianness is
+// not an issue here, as we're comparing for equality.
+
+static int
+hashCollision(SbeXipHashedToc* i_fixedToc, size_t i_entries)
+{
+ int rc;
+ size_t i, j;
+
+ rc = 0;
+
+ for (i = 0; i < i_entries; i++) {
+ for (j = i + 1; j < i_entries; j++) {
+ if (i_fixedToc[i].iv_hash == i_fixedToc[j].iv_hash) {
+ rc = TRACE_ERRORX(SBE_XIP_HASH_COLLISION,
+ "Hash collision at index %d\n",
+ i);
+ break;
+ }
+ }
+ if (rc) break;
+ }
+
+ return rc;
+}
+
+
/// Decode a normalized image-format TOC entry into a host-format SbeXipItem
/// structure
@@ -945,6 +1053,8 @@ decodeToc(void* i_image,
o_item->iv_address =
linkAddress(i_image) + dataSection.iv_offset + hostToc.iv_data;
+
+ o_item->iv_partial = 0;
} while (0);
return rc;
@@ -1020,6 +1130,92 @@ padImage(void* io_image, uint32_t i_allocation,
}
+// Get the .fixed_toc section
+
+static int
+getFixedToc(void* io_image,
+ SbeXipHashedToc** o_imageToc,
+ size_t* o_entries)
+{
+ int rc;
+ SbeXipSection section;
+
+ rc = sbe_xip_get_section(io_image, SBE_XIP_SECTION_FIXED_TOC, &section);
+ if (!rc) {
+
+ *o_imageToc =
+ (SbeXipHashedToc*)((unsigned long)io_image + section.iv_offset);
+
+ *o_entries = section.iv_size / sizeof(SbeXipHashedToc);
+ }
+
+ return rc;
+}
+
+
+// Search for an item in the fixed TOC, and populate a partial TOC entry if
+// requested. This table is small and unsorted so a linear search is
+// adequate. The TOC structures are also small so all byte-reversal is done
+// 'by hand' rather than with a translate-type API.
+
+static int
+fixedFind(void* i_image, const char* i_id, SbeXipItem* o_item)
+{
+ int rc;
+ SbeXipHashedToc* toc;
+ size_t entries;
+ uint32_t hash;
+ SbeXipSection fixedSection;
+ uint32_t offset;
+
+ do {
+ rc = getFixedToc(i_image, &toc, &entries);
+ if (rc) break;
+
+ for (hash = revle32(hash32(i_id)); entries != 0; entries--, toc++) {
+ if (toc->iv_hash == hash) break;
+ }
+
+ if (entries == 0) {
+ rc = SBE_XIP_ITEM_NOT_FOUND;
+ break;
+ } else {
+ rc = 0;
+ }
+
+ // The caller may have requested a lookup only (o_item == 0), in which
+ // case we're done. Otherwise we create a partial SbeXipItem and
+ // populate the non-0 fields analogously to the decodeToc()
+ // routine. The data resides in the .fixed section in this case.
+
+ if (o_item == 0) break;
+
+ o_item->iv_partial = 1;
+ o_item->iv_toc = 0;
+ o_item->iv_id = 0;
+
+ o_item->iv_type = toc->iv_type;
+ o_item->iv_elements = toc->iv_elements;
+
+ rc = sbe_xip_get_section(i_image, SBE_XIP_SECTION_FIXED, &fixedSection);
+ if (rc) break;
+
+ if (fixedSection.iv_size == 0) {
+ rc = TRACE_ERROR(SBE_XIP_DATA_NOT_PRESENT);
+ break;
+ }
+
+ offset = fixedSection.iv_offset + revle16(toc->iv_offset);
+
+ o_item->iv_imageData = (void*)((uint8_t*)i_image + offset);
+ o_item->iv_address = linkAddress(i_image) + offset;
+
+ } while (0);
+
+ return rc;
+}
+
+
////////////////////////////////////////////////////////////////////////////
// Published API
////////////////////////////////////////////////////////////////////////////
@@ -1054,6 +1250,14 @@ sbe_xip_validate(void* i_image, const uint32_t i_size)
break;
}
+ if (sizeof(SbeXipHashedToc) != SIZE_OF_SBE_XIP_HASHED_TOC) {
+ rc = TRACE_ERRORX(SBE_XIP_BUG,
+ "C/Assembler size mismatch(%d/%d) "
+ "for SbeXipHashedToc\n",
+ sizeof(SbeXipHashedToc), SIZE_OF_SBE_XIP_HASHED_TOC);
+ break;
+ }
+
// Validate the image pointer and magic number
rc = quickCheck(i_image, 0);
@@ -1160,20 +1364,41 @@ sbe_xip_normalize(void* io_image)
int rc, i;
SbeXipSection section;
SbeXipToc* imageToc;
- size_t entries;
+ SbeXipHashedToc* fixedImageToc;
+ SbeXipHashedToc* fixedTocEntry;
+ size_t tocEntries, fixedTocEntries, fixedEntriesRemaining;
do {
rc = quickCheck(io_image, 0);
if (rc) break;
if (!normalized(io_image)) {
- rc = getToc(io_image, &imageToc, &entries, 0, 0);
+
+ rc = getToc(io_image, &imageToc, &tocEntries, 0, 0);
if (rc) break;
- for (; entries--; imageToc++) {
- rc = normalizeToc(io_image, imageToc);
- if (rc) break;
+
+ rc = getFixedToc(io_image, &fixedImageToc, &fixedTocEntries);
+ if (rc) break;
+
+ fixedTocEntry = fixedImageToc;
+ fixedEntriesRemaining = fixedTocEntries;
+
+ for (; tocEntries--; imageToc++) {
+ rc = normalizeToc(io_image, imageToc,
+ &fixedTocEntry, &fixedEntriesRemaining);
+
+ }
+ if (rc) break;
+
+ if (fixedEntriesRemaining != 0) {
+ rc = TRACE_ERRORX(SBE_XIP_TOC_ERROR,
+ "Not enough TOC entries for .fixed");
+ break;
}
+
+ rc = hashCollision(fixedImageToc, fixedTocEntries);
if (rc) break;
+
((SbeXipHeader*)io_image)->iv_normalized = 1;
}
@@ -1228,6 +1453,9 @@ sbe_xip_get_section(const void* i_image,
}
+// If the 'big' TOC is not present, search the mini-TOC that only indexes the
+// fixed section.
+
int
sbe_xip_find(void* i_image,
const char* i_id,
@@ -1236,11 +1464,20 @@ sbe_xip_find(void* i_image,
int rc;
SbeXipToc* toc;
SbeXipItem item, *pitem;
+ SbeXipSection* tocSection;
do {
rc = quickCheck(i_image, 1);
if (rc) break;
+ rc = getSectionPointer(i_image, SBE_XIP_SECTION_TOC, &tocSection);
+ if (rc) break;
+
+ if (tocSection->iv_size == 0) {
+ rc = fixedFind(i_image, i_id, o_item);
+ break;
+ }
+
if (sorted(i_image)) {
rc = binarySearch(i_image, i_id, &toc);
} else {
@@ -1920,8 +2157,8 @@ sbe_xip_translate_header(SbeXipHeader* o_dest, const SbeXipHeader* i_src)
SbeXipSection* destSection;
const SbeXipSection* srcSection;
-#if SBE_XIP_HEADER_VERSION != 7
-#error This code assumes the SBE-XIP header version 7 layout
+#if SBE_XIP_HEADER_VERSION != 8
+#error This code assumes the SBE-XIP header version 8 layout
#endif
o_dest->iv_magic = revle64(i_src->iv_magic);
diff --git a/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/sbe_xip_image.h b/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/sbe_xip_image.h
index 081f368e8..02421cd30 100644
--- a/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/sbe_xip_image.h
+++ b/src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/sbe_xip_image.h
@@ -24,7 +24,7 @@
#ifndef __SBE_XIP_IMAGE_H
#define __SBE_XIP_IMAGE_H
-// $Id: sbe_xip_image.h,v 1.15 2012/05/22 03:26:27 bcbrock Exp $
+// $Id: sbe_xip_image.h,v 1.18 2012/07/06 20:03:09 bcbrock Exp $
// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/sbe/sbe_xip_image.h,v $
//-----------------------------------------------------------------------------
// *! (C) Copyright International Business Machines Corp. 2011
@@ -45,7 +45,7 @@
/// If any changes are made to this file or to sbe_xip_header.H, please update
/// the header version and follow-up on all of the error messages.
-#define SBE_XIP_HEADER_VERSION 7
+#define SBE_XIP_HEADER_VERSION 8
/// \defgroup sbe_xip_magic_numbers SBE-XIP magic numbers
///
@@ -79,18 +79,18 @@
#define SBE_XIP_SECTION_HEADER 0
#define SBE_XIP_SECTION_FIXED 1
-#define SBE_XIP_SECTION_IPL_TEXT 2
-#define SBE_XIP_SECTION_IPL_DATA 3
-#define SBE_XIP_SECTION_TEXT 4
-#define SBE_XIP_SECTION_DATA 5
-#define SBE_XIP_SECTION_TOC 6
-#define SBE_XIP_SECTION_STRINGS 7
-#define SBE_XIP_SECTION_PIBMEM0 8
-#define SBE_XIP_SECTION_PIBMEM1 9
-#define SBE_XIP_SECTION_RINGS 10
-#define SBE_XIP_SECTION_HALT 11
-#define SBE_XIP_SECTION_SLW 12
-#define SBE_XIP_SECTION_RESERVED_2 13
+#define SBE_XIP_SECTION_FIXED_TOC 2
+#define SBE_XIP_SECTION_IPL_TEXT 3
+#define SBE_XIP_SECTION_IPL_DATA 4
+#define SBE_XIP_SECTION_TEXT 5
+#define SBE_XIP_SECTION_DATA 6
+#define SBE_XIP_SECTION_TOC 7
+#define SBE_XIP_SECTION_STRINGS 8
+#define SBE_XIP_SECTION_HALT 9
+#define SBE_XIP_SECTION_PIBMEM0 10
+#define SBE_XIP_SECTION_PIBMEM1 11
+#define SBE_XIP_SECTION_RINGS 12
+#define SBE_XIP_SECTION_SLW 13
#define SBE_XIP_SECTION_RESERVED_1 14
#define SBE_XIP_SECTION_RESERVED_0 15
@@ -105,18 +105,18 @@
const char* var[] = { \
".header", \
".fixed", \
+ ".fixed_toc", \
".ipl_text", \
".ipl_data", \
".text", \
".data", \
".toc", \
".strings", \
+ ".halt", \
".pibmem0", \
".pibmem1", \
".rings", \
- ".halt", \
".slw", \
- ".reserved_2", \
".reserved_1", \
".reserved_0" \
}
@@ -134,7 +134,7 @@
/// Maximum section alignment for SBE-XIP sections
#define SBE_XIP_MAX_SECTION_ALIGNMENT 128
-/// defgroup sbe_xip_toc_types SBE-XIP Table of Contents data types
+/// \defgroup sbe_xip_toc_types SBE-XIP Table of Contents data types
///
/// These are the data types stored in the \a iv_type field of the SbeXipToc
/// objects. These must be defined as manifest constants because they are
@@ -446,19 +446,70 @@ typedef struct {
#define SIZE_OF_SBE_XIP_TOC 12
+/// A C-structure form of hashed SBE-XIP Table of Contents (TOC) entries
+///
+/// This structure was introduced in order to allow a small TOC for the .fixed
+/// section to support minimum-sized SEEPROM images in which the global TOC
+/// and all strings have been stripped out. In this structure the index
+/// string has been replaced by a 32-bit hash, and there is no longer a record
+/// of the original data name other then the hash. The section of the data is
+/// assumed to be .fixed, with a maximum 16-bit offset.
+///
+/// These structures are created when entries are made in the .fixed section.
+/// They are created empty, then filled in during image normalization.
+///
+/// This structure allows the sbe_xip_get*() and sbe_xip_set*() APIs to work
+/// even on highly-stripped SEEPROM images.
+
+typedef struct {
+
+ /// A 32-bit hash (FNV-1a) of the Id string.
+ uint32_t iv_hash;
+
+ /// The offset in bytes from the start of the (implied) section of the data
+ uint16_t iv_offset;
+
+ /// The type of the data; See \ref sbe_xip_toc_types.
+ uint8_t iv_type;
+
+ /// The number of elements for vector types, otherwise 1 for scalar types
+ /// and addresses.
+ ///
+ /// Vectors are naturally limited in size, e.g. to the number of cores,
+ /// chips in a node, DD-levels etc. If \a iv_elements is 0 then no bounds
+ /// checking is done on get/set accesses of the data.
+ uint8_t iv_elements;
+
+} SbeXipHashedToc;
+
+/// The SbeXipHashedToc structure is created by assembler code and is expected
+/// to have the same size in C code. This constraint is checked in
+/// sbe_xip_validate().
+#define SIZE_OF_SBE_XIP_HASHED_TOC 8
+
+
/// A decoded TOC entry for use by applications
///
/// This structure is a decoded form of a normalized TOC entry, filled in by
/// the sbe_xip_decode_toc() and sbe_xip_find() APIs. This structure is
-/// always returned with data elements in host-endian format.
+/// always returned with data elements in host-endian format.
+///
+/// In the event that the TOC has been removed from the image, this structure
+/// will also be returned by sbe_xip_find() with information populated from
+/// the .fixed_toc section if possible. In this case the field \a iv_partial
+/// will be set and only the fields \a iv_address, \a iv_imageData, \a iv_type
+/// and \a iv_elements will be populated (all other fields will be set to 0).
///
/// \note Only special-purpose applications will ever need to use this
/// structure given that the higher-level APIs sbe_xip_get_*() and
-/// sbe_xip_set_*() are provided and shoudl be used if possible.
+/// sbe_xip_set_*() are provided and should be used if possible, especially
+/// given that the information may be truncated as described above.
typedef struct {
/// A pointer to the associated TOC entry as it exists in the image
+ ///
+ /// If \a iv_partial is set this field is returned as 0.
SbeXipToc* iv_toc;
/// The full relocatable PORE address
@@ -466,7 +517,7 @@ typedef struct {
/// All relocatable addresses are computed from the \a iv_linkAddress
/// stored in the header. For scalar and string data, this is the
/// relocatable address of the data. For address-only entries, this is
- /// the indexed address itself.
+ /// the indexed address itself.
uint64_t iv_address;
/// A host pointer to the first byte of text or data within the image
@@ -483,7 +534,8 @@ typedef struct {
///
/// This is a pointer in host memory to a string that names the TOC entry
/// requested. This field is set to a pointer to the ID string of the TOC
- /// entry inside the image.
+ /// entry inside the image. If \a iv_partial is set this field is returned
+ /// as 0.
char* iv_id;
/// The data type, one of the SBE_XIP_* constants
@@ -497,6 +549,13 @@ typedef struct {
/// used to bounds check indexed accesses.
uint8_t iv_elements;
+ /// Is this record only partially populated?
+ ///
+ /// This field is set to 0 normally, and only set to 1 if a lookup is made
+ /// in an image that only has the fixed TOC and the requested Id hashes to
+ /// the fixed TOC.
+ uint8_t iv_partial;
+
} SbeXipItem;
@@ -800,7 +859,7 @@ sbe_xip_set_element(void *i_image,
/// Set string data in an SBE-XIP image
///
-/// \param[in] i_image A pointer to an SBE-XIP image in host memory. The
+/// \param[in,out] io_image A pointer to an SBE-XIP image in host memory. The
/// image is assumed to be consistent with the information contained in the
/// header regarding the presence of and sizes of all sections. The image is
/// also required to have been normalized.
@@ -882,7 +941,7 @@ sbe_xip_write_uint64(void *io_image,
/// \retval 0 Success; All TOC entries were mapped, including the case that
/// the .toc section is empty.
///
-/// \revtal non-0 May be either one of the SBE-XIP image error codes (see \ref
+/// \retval non-0 May be either one of the SBE-XIP image error codes (see \ref
/// sbe_xip_image_errors), or a non-zero code from \a i_fn. Since the standard
/// SBE_XIP return codes are > 0, application-defined codes should be < 0.
int
@@ -920,9 +979,16 @@ sbe_xip_map_toc(void* io_image,
/// - SBE_XIP_DATA_NOT_PRESENT : The item appears in the TOC, however the
/// section containing the data is no longer present in the image.
///
-/// \note This API should not be used unless absolutely necessary. To obtain
-/// data from the image or update data in the image use the sbe_xip_get_*()
-/// and sbe_xip_set_*() APIs respectively whenever possible.
+/// If the TOC section has been deleted from the image, then the search is
+/// restricted to the abbreviated TOC that indexes data in the .fixed section.
+/// In this case the \a o_item structure is marked with a 1 in the \a
+/// iv_partial field since the abbreviated TOC can not populate the entire
+/// SbeXipItem structure.
+///
+/// \note This API should typically only be used as a predicate, not as a way
+/// to access the image via the returned SbeXipItem structure. To obtain data
+/// from the image or update data in the image use the sbe_xip_get_*() and
+/// sbe_xip_set_*() APIs respectively.
///
/// \retval 0 Success
///
@@ -948,6 +1014,8 @@ sbe_xip_find(void* i_image,
/// const char* i_rcString,
/// void* io_arg)
///
+/// \endcode
+///
/// \param[in,out] io_arg The private argument of \a i_fn.
///
/// This API iterates over each entry of the .halt section, calling \a i_fn
@@ -959,10 +1027,10 @@ sbe_xip_find(void* i_image,
///
/// \retval 0 Success, including the case that the image has no .halt section.
///
-/// \revtal non-0 May be either one of the SBE-XIP image error codes (see \ref
+/// \retval non-0 May be either one of the SBE-XIP image error codes (see \ref
/// sbe_xip_image_errors), or any non-zero code from \a i_fn. Since the
-/// standard SBE_XIP return codes are > 0, application-defined codes should be
-/// < 0.
+/// standard SBE_XIP return codes are \> 0, application-defined codes should
+/// be \< 0.
int
sbe_xip_map_halt(void* io_image,
int (*i_fn)(void* io_image,
@@ -989,19 +1057,19 @@ sbe_xip_map_halt(void* io_image,
///
/// \retval 0 Success
///
-/// \retval SBE_XIP_ITEM_NOT_FOUND The \a i_poreAddress is not associated
+/// \revtal SBE_XIP_ITEM_NOT_FOUND The \a i_poreAddress is not associated
/// with a halt code in .halt.
///
/// \revtal Other See \ref sbe_xip_image_errors
int
sbe_xip_get_halt(void* io_image,
- const uint64_t i_poreAdress,
+ const uint64_t i_poreAddress,
const char** o_rcString);
/// Delete a section from an SBE-XIP image in host memory
///
-/// \param[in,out] i_image A pointer to an SBE-XIP image in host memory. The
+/// \param[in,out] io_image A pointer to an SBE-XIP image in host memory. The
/// image is assumed to be consistent with the information contained in the
/// header regarding the presence of and sizes of all sections. The image is
/// also required to have been normalized.
@@ -1041,10 +1109,10 @@ sbe_xip_delete_section(void* io_image, const int i_sectionId);
/// section.
///
/// This API creates a bytewise duplicate of a non-empty section into newly
-/// malloc()-ed memory. At exit \a o_duplicate points to the duplicate, and \i
+/// malloc()-ed memory. At exit \a o_duplicate points to the duplicate, and \a
/// o_size is set the the size of the duplicated section. The caller is
/// responsible for free()-ing the memory when no longer required. The
-/// pointer at \o_duplicate is set to NULL (0) and teh \a o_size is set to 0
+/// pointer at \a o_duplicate is set to NULL (0) and the \a o_size is set to 0
/// in the event of any failure.
///
/// \retval 0 Success
@@ -1054,7 +1122,7 @@ int
sbe_xip_duplicate_section(const void* i_image,
const int i_sectionId,
void** o_duplicate,
- uint32_t* size);
+ uint32_t* o_size);
/// Append binary data to an SBE-XIP image held in host memory
@@ -1251,7 +1319,7 @@ sbe_xip_pore2section(const void* i_image,
int
sbe_xip_host2pore(const void* i_image,
void* i_hostAddress,
- uint64_t* i_poreAddress);
+ uint64_t* o_poreAddress);
/// \defgroup sbe_xip_image_errors Error codes from SBE-XIP image APIs
@@ -1285,7 +1353,7 @@ sbe_xip_host2pore(const void* i_image,
/// A data type mismatch or an illegal type was specified or implied for an
/// operation.
-#define SBE_XIP_TYPE_ERROR 8
+#define SBE_XIP_TYPE_ERROR 7
/// A bug in an SBE-XIP image API
#define SBE_XIP_BUG 8
@@ -1318,6 +1386,9 @@ sbe_xip_host2pore(const void* i_image,
/// Error associated with the disassembler occured.
#define SBE_XIP_DISASSEMBLER_ERROR 15
+/// hash collision creating the .fixed_toc section
+#define SBE_XIP_HASH_COLLISION 16
+
/// Applications can expand this macro to declare an array of string forms of
/// the error codes if desired.
#define SBE_XIP_ERROR_STRINGS(var) \
@@ -1338,6 +1409,7 @@ sbe_xip_host2pore(const void* i_image,
"SBE_XIP_BOUNDS_ERROR", \
"SBE_XIP_WOULD_OVERFLOW", \
"SBE_XIP_DISASSEMBLER_ERROR", \
+ "SBE_XIP_HASH_COLLISION", \
}
/// Applications can use this macro to safely index the array of error
diff --git a/src/usr/hwpf/hwp/core_activate/core_activate.C b/src/usr/hwpf/hwp/core_activate/core_activate.C
index e4ecf4ba1..e3d5596af 100644
--- a/src/usr/hwpf/hwp/core_activate/core_activate.C
+++ b/src/usr/hwpf/hwp/core_activate/core_activate.C
@@ -71,56 +71,143 @@ using namespace fapi;
using namespace ISTEP;
+
//
// Wrapper function to call 16.1 :
// host_activate_master
//
-void call_host_activate_master( void *io_pArgs )
-{
- errlHndl_t l_errl = NULL;
+ void call_host_activate_master( void *io_pArgs )
+ {
+ errlHndl_t l_errl = NULL;
- TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "call_host_activate_master entry" );
+ TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "call_host_activate_master entry" );
-#if 0
- // @@@@@ CUSTOM BLOCK: @@@@@
- // figure out what targets we need
- // customize any other inputs
- // set up loops to go through all targets (if parallel, spin off a task)
-
- // dump physical path to targets
- EntityPath l_path;
- l_path = l_@targetN_target->getAttr<ATTR_PHYS_PATH>();
- l_path.dump();
-
- // cast OUR type of target to a FAPI type of target.
- const fapi::Target l_fapi_@targetN_target(
- TARGET_TYPE_MEMBUF_CHIP,
- reinterpret_cast<void *>
- (const_cast<TARGETING::Target*>(l_@targetN_target)) );
-
- // call the HWP with each fapi::Target
- FAPI_INVOKE_HWP( l_errl, host_activate_master, _args_...);
- if ( l_errl )
- {
- TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
- "ERROR : .........." );
- errlCommit( l_errl, HWPF_COMP_ID );
- }
- else
- {
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "SUCCESS : .........." );
- }
- // @@@@@ END CUSTOM BLOCK: @@@@@
+ // @@@@@ CUSTOM BLOCK: @@@@@
+
+ do {
+
+ // find the master core, i.e. the one we are running on
+ TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "call_host_activate_master: Find master core: " );
+
+ const TARGETING::Target* l_masterCore = getMasterCore( );
+ assert( l_masterCore != NULL );
+
+ TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "call_host_activate_master: Find master chip: " );
+ TARGETING::Target* l_cpu_target = const_cast<TARGETING::Target *>
+ ( getParentChip( l_masterCore ) );
+
+ // dump physical path to target
+ EntityPath l_path;
+ l_path = l_cpu_target->getAttr<ATTR_PHYS_PATH>();
+ l_path.dump();
+
+ // cast OUR type of target to a FAPI type of target.
+ const fapi::Target l_fapi_cpu_target(
+ TARGET_TYPE_PROC_CHIP,
+ reinterpret_cast<void *>
+ (const_cast<TARGETING::Target*>(l_cpu_target)) );
+
+
+#if 1
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Call proc_prep_master_winkle when integrated..." );
+#else
+ // call the HWP with each fapi::Target
+ FAPI_INVOKE_HWP( l_errl,
+ proc_prep_master_winkle,
+ l_fapi_cpu_target );
#endif
+ if ( l_errl )
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "proc_prep_master_winkle ERROR : Returning errorlog, PLID=0x%x",
+ l_errl->plid() );
+ break;
+ }
+ else
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "proc_prep_master_winkle SUCCESS" );
+ }
- TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "call_host_activate_master exit" );
+ // put the master into winkle.
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "call_host_activate_master: put master into winkle..." );
- // end task, returning any errorlogs to IStepDisp
- task_end2( l_errl );
-}
+ // @todo 2012-07-30 currently this is just a stub...
+ int l_rc = cpu_master_winkle( );
+ if ( l_rc )
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "ERROR : failed to winkle master, rc=0x%x",
+ l_rc );
+ /*@
+ * @errortype
+ * @reasoncode ISTEP_FAIL_MASTER_WINKLE_RC
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid ISTEP_CORE_ACTIVATE
+ * @userdata1 return code from cpu_master_winkle
+ *
+ * @devdesc p8_pore_gen_cpureg returned an error when
+ * attempting to change a reg value in the PORE image.
+ */
+ l_errl =
+ new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ ISTEP_CORE_ACTIVATE,
+ ISTEP_FAIL_MASTER_WINKLE_RC,
+ l_rc );
+ break;
+ }
+
+
+ // --------------------------------------------------------
+ // $$ @todo do something to trigger IPI at this point.
+ // MAGIC_INSTRUCTION( ???? );
+ // --------------------------------------------------------
+
+
+ // --------------------------------------------------------
+ // should return from Winkle at this point
+ // --------------------------------------------------------
+
+
+#if 1
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Call proc_stop_deadman_timer when integrated..." );
+#else
+ // call the HWP with each fapi::Target
+ FAPI_INVOKE_HWP( l_errl,
+ proc_stop_deadman_timer,
+ l_fapi_cpu_target );
+#endif
+ if ( l_errl )
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "proc_stop_deadman_timer ERROR : Returning errorlog, PLID=0x%x",
+ l_errl->plid() );
+ break;
+ }
+ else
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "proc_prep_master_winkle SUCCESS" );
+ }
+
+ } while ( 0 );
+
+ // @@@@@ END CUSTOM BLOCK: @@@@@
+
+
+ TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "call_host_activate_master exit" );
+
+ // end task, returning any errorlogs to IStepDisp
+ task_end2( l_errl );
+
+ }
diff --git a/src/usr/hwpf/makefile b/src/usr/hwpf/makefile
index 8b58435fa..99b51dd3f 100644
--- a/src/usr/hwpf/makefile
+++ b/src/usr/hwpf/makefile
@@ -41,7 +41,9 @@ HWP_ERROR_XML_FILES = hwp/fapiHwpErrorInfo.xml \
hwp/mvpd_errors.xml \
../pore/fapiporeve/fapiPoreVe_errors.xml \
hwp/dram_initialization/proc_setup_bars/proc_setup_bars_errors.xml \
- hwp/dram_initialization/proc_setup_bars/proc_fab_smp_errors.xml
+ hwp/dram_initialization/proc_setup_bars/proc_fab_smp_errors.xml \
+ hwp/build_winkle_images/proc_set_pore_bar/proc_set_pore_bar_errors.xml \
+ hwp/build_winkle_images/proc_pba_bar_config/proc_pba_bar_config_errors.xml
diff --git a/src/usr/pnor/pnordd.C b/src/usr/pnor/pnordd.C
index 2468b470d..4801e07a2 100644
--- a/src/usr/pnor/pnordd.C
+++ b/src/usr/pnor/pnordd.C
@@ -1404,9 +1404,19 @@ errlHndl_t PnorDD::eraseFlash(uint32_t i_address)
This code is used in the MODEL_MEMCPY and MODEL_LPC_MEM modes
*/
-#define FAKE_PNOR_START 4*MEGABYTE
+// $$ #define FAKE_PNOR_START 4*MEGABYTE
+// $$ #define FAKE_PNOR_END 8*MEGABYTE
+// $$ #define FAKE_PNOR_SIZE 4*MEGABYTE
+//
+// @note fake pnor is moved up and shrunk by 1/2 meg to make room for
+// the SLW image, it must be at a 1 M boundary.
+// See build_winkle_images for more info.
+//
+#define FAKE_PNOR_START 4*MEGABYTE+5*KILOBYTE
#define FAKE_PNOR_END 8*MEGABYTE
-#define FAKE_PNOR_SIZE 4*MEGABYTE
+#define FAKE_PNOR_SIZE 3*MEGABYTE
+
+
void write_fake_pnor( uint64_t i_pnorAddr, void* i_buffer, size_t i_size )
{
//create a pointer to the offset start.
diff --git a/src/usr/targeting/common/utilFilter.C b/src/usr/targeting/common/utilFilter.C
index f6fcc3756..20acaf170 100644
--- a/src/usr/targeting/common/utilFilter.C
+++ b/src/usr/targeting/common/utilFilter.C
@@ -32,6 +32,8 @@
#include <targeting/common/predicates/predicateisfunctional.H>
#include <targeting/common/predicates/predicatepostfixexpr.H>
+#include <sys/task.h> // task_getcpuid()
+
/**
* Miscellaneous Filter Utility Functions
@@ -209,4 +211,56 @@ const Target * getParentChip( const Target * i_pChiplet )
return l_pChip;
}
-};
+
+const TARGETING::Target * getMasterCore( )
+{
+ uint64_t l_masterCoreID = task_getcpuid() & ~7;
+ const TARGETING::Target * l_masterCore = NULL;
+
+ TARGETING::Target * l_processor = NULL;
+ (void)TARGETING::targetService().masterProcChipTargetHandle( l_processor );
+ FABRIC_NODE_ID_ATTR l_logicalNodeId =
+ l_processor->getAttr<TARGETING::ATTR_FABRIC_NODE_ID>();
+ FABRIC_CHIP_ID_ATTR l_chipId =
+ l_processor->getAttr<TARGETING::ATTR_FABRIC_CHIP_ID>();
+
+ TargetHandleList l_cores;
+ getChildChiplets( l_cores,
+ l_processor,
+ TYPE_CORE,
+ true );
+
+ TRACDCOMP( g_trac_targeting,
+ "getMasterCore: found %d cores on master proc",
+ l_cores.size() );
+
+ for ( uint8_t l_coreNum=0; l_coreNum < l_cores.size(); l_coreNum++ )
+ {
+ TARGETING::Target * l_core = l_cores[ l_coreNum ] ;
+
+ CHIP_UNIT_ATTR l_coreId =
+ l_core->getAttr<TARGETING::ATTR_CHIP_UNIT>();
+
+ uint64_t pir = l_coreId << 3;
+ pir |= l_chipId << 7;
+ pir |= l_logicalNodeId << 10;
+
+ if (pir == l_masterCoreID){
+ TRACDCOMP( g_trac_targeting,
+ "found master core: 0x%x, PIR=0x%x :",
+ l_coreId,
+ pir );
+ EntityPath l_path;
+ l_path = l_core->getAttr<ATTR_PHYS_PATH>();
+ l_path.dump();
+
+ l_masterCore = l_core ;
+ break;
+ }
+
+ } // endfor
+
+ return l_masterCore;
+}
+
+}; // end namespace
diff --git a/src/usr/targeting/common/xmltohb/attribute_types.xml b/src/usr/targeting/common/xmltohb/attribute_types.xml
index 6626b2906..a032aaaf9 100644
--- a/src/usr/targeting/common/xmltohb/attribute_types.xml
+++ b/src/usr/targeting/common/xmltohb/attribute_types.xml
@@ -4011,4 +4011,32 @@
</hwpfToHbAttrMap>
</attribute>
+<attribute>
+ <id>SLW_IMAGE_ADDR</id>
+ <description>
+ Location of runtime winkle image for this processor chip.
+ Written by host_build_winkle (istep 15.1)
+ </description>
+ <simpleType>
+ <uint64_t></uint64_t>
+ </simpleType>
+ <persistency>volatile-zeroed</persistency>
+ <readable/>
+ <writeable/>
+</attribute>
+
+<attribute>
+ <id>SLW_IMAGE_SIZE</id>
+ <description>
+ Size of runtime winkle image for this processor chip.
+ Written by host_build_winkle (istep 15.1)
+ </description>
+ <simpleType>
+ <uint64_t></uint64_t>
+ </simpleType>
+ <persistency>volatile-zeroed</persistency>
+ <readable/>
+ <writeable/>
+</attribute>
+
</attributes>
diff --git a/src/usr/targeting/common/xmltohb/target_types.xml b/src/usr/targeting/common/xmltohb/target_types.xml
index ba3bce39d..7be57fcef 100644
--- a/src/usr/targeting/common/xmltohb/target_types.xml
+++ b/src/usr/targeting/common/xmltohb/target_types.xml
@@ -204,7 +204,9 @@
<!-- proc_fab_smp_fabric_attributes.xml -->
<attribute><id>FREQ_CORE</id></attribute>
<attribute><id>PROC_PCIE_NOT_F_LINK</id></attribute>
-
+ <!-- new attribute for isteps 15 & 16 -->
+ <attribute><id>SLW_IMAGE_ADDR</id></attribute>
+ <attribute><id>SLW_IMAGE_SIZE</id></attribute>
</targetType>
<targetType>
OpenPOWER on IntegriCloud