diff options
-rw-r--r-- | sbe/image/Makefile | 37 | ||||
-rw-r--r-- | sbe/image/base_loader.c | 6 | ||||
-rw-r--r-- | sbe/image/base_main.C | 1 | ||||
-rw-r--r-- | sbe/image/base_ppe_header.S | 66 | ||||
-rw-r--r-- | sbe/image/base_sbe_fixed.S | 2 | ||||
-rw-r--r-- | sbe/image/fapi_sbe_common.H | 47 | ||||
-rw-r--r-- | sbe/image/img_defs.mk | 10 | ||||
-rw-r--r-- | sbe/image/sbe_common.H | 22 | ||||
-rw-r--r-- | sbe/image/sbe_loader.c | 6 | ||||
-rw-r--r-- | sbe/image/sbe_xip_image.c | 2460 | ||||
-rw-r--r-- | sbe/image/sbe_xip_image.h | 1724 | ||||
-rw-r--r-- | tools/image/Makefile | 24 | ||||
-rw-r--r-- | tools/image/p9_image_help_base.H | 95 | ||||
-rw-r--r-- | tools/image/p9_ring_identification.H | 41 | ||||
-rw-r--r-- | tools/image/p9_ring_identification.c | 122 | ||||
-rw-r--r-- | tools/image/p9_scan_compression.H | 345 | ||||
-rw-r--r-- | tools/image/sbe_default_tool.c | 52 | ||||
-rw-r--r-- | tools/image/sbe_xip_tool.c | 2107 |
18 files changed, 120 insertions, 7047 deletions
diff --git a/sbe/image/Makefile b/sbe/image/Makefile index 39f84e83..22ae0657 100644 --- a/sbe/image/Makefile +++ b/sbe/image/Makefile @@ -93,7 +93,9 @@ LIB_DIRS += -L$(OBJDIR)/nest NESTLIB := $(OBJDIR)/nest/libnest.a LLIBS += -lnest -SBE_TOOLS := $(TOOLS_IMAGE_DIR)/sbe_xip_tool $(TOOLS_IMAGE_DIR)/sbe_default_tool +SBE_TOOLS := $(TOOLS_IMAGE_DIR)/sbe_default_tool + +P9_XIP_TOOL := $(P9_XIP_BINDIR)/p9_xip_tool LINK_OBJS = $(OBJS) $(SBEFWLIB) $(PKLIB) $(FAPI2LIB) $(CACHELIB) $(CORELIB) $(HWPLIB) $(P2PLIB) $(PERVLIB) $(NESTLIB) @@ -175,19 +177,19 @@ endif all: $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin $(OBJDIR)/$(IMAGE_SBE_NAME).bin $(OBJDIR)/$(IMAGE_LOADER_NAME).bin $(SBE_TOOLS) normalize defaultset $(OBJDIR)/fixed.bin appendbase appendloader add_entry_offset add_entry_address_sbe symbols tracehash -add_entry_offset: $(OBJDIR)/$(IMAGE_SEEPROM_NAME).out - $(TOOLS_IMAGE_DIR)/sbe_xip_tool $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin set entry_offset 0x`nm $(OBJDIR)/$(IMAGE_SEEPROM_NAME).out | grep sbe_loader | cut -f 1 -d " "` +add_entry_offset: $(P9_XIP_TOOL) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).out + $(P9_XIP_TOOL) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin set entry_offset 0x`nm $(OBJDIR)/$(IMAGE_SEEPROM_NAME).out | grep sbe_loader | cut -f 1 -d " "` -add_entry_address_sbe: $(OBJDIR)/$(IMAGE_LOADER_NAME).out - $(TOOLS_IMAGE_DIR)/sbe_xip_tool $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin set entry_address_sbe 0x`nm $(OBJDIR)/$(IMAGE_LOADER_NAME).out | grep base_loader | cut -f 1 -d " "` +add_entry_address_sbe: $(P9_XIP_TOOL) $(OBJDIR)/$(IMAGE_LOADER_NAME).out + $(P9_XIP_TOOL) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin set entry_address_sbe 0x`nm $(OBJDIR)/$(IMAGE_LOADER_NAME).out | grep base_loader | cut -f 1 -d " "` symbols: $(OBJDIR)/$(IMAGE_SEEPROM_NAME).out $(OBJDIR)/$(IMAGE_LOADER_NAME).out $(OBJDIR)/$(IMAGE_SBE_NAME).out $(NM) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).out > $(OBJDIR)/$(SBE_SYMBOLS_NAME) $(NM) $(OBJDIR)/$(IMAGE_LOADER_NAME).out >> $(OBJDIR)/$(SBE_SYMBOLS_NAME) $(NM) $(OBJDIR)/$(IMAGE_SBE_NAME).out >> $(OBJDIR)/$(SBE_SYMBOLS_NAME) -seeprom: $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin $(SBE_TOOLS) normalize defaultset $(OBJDIR)/fixed.bin - $(TOOLS_IMAGE_DIR)/sbe_xip_tool $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin report > $(OBJDIR)/$(IMAGE_SEEPROM_NAME).rpt +seeprom: $(P9_XIP_TOOL) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin $(SBE_TOOLS) normalize defaultset $(OBJDIR)/fixed.bin + $(P9_XIP_TOOL) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin report > $(OBJDIR)/$(IMAGE_SEEPROM_NAME).rpt # Create build Info file buildInfo: @@ -283,8 +285,12 @@ endif $(SBE_TOOLS): $(MAKE) -C $(TOOLS_IMAGE_DIR) -f Makefile -normalize: $(SBE_TOOLS) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin - $(TOOLS_IMAGE_DIR)/sbe_xip_tool $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin normalize +# Build the P9-XIP Tool +$(P9_XIP_TOOL): + $(MAKE) -I $(P9_XIP_SRCDIR) -C $(P9_XIP_SRCDIR) -f Makefile #$(P9_XIP_TOOL) + +normalize: $(P9_XIP_TOOL) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin + $(P9_XIP_TOOL) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin normalize defaultset: $(SBE_TOOLS) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin normalize $(TOOLS_IMAGE_DIR)/ppeSetFixed.pl $(TOOLS_IMAGE_DIR) $(BASE_OBJDIR)/$(IMAGE_SEEPROM_NAME).bin $(IMPORT_XML_DIR)/attribute_info/p9_sbe_attributes.xml $(ATTRFILES) @@ -311,17 +317,17 @@ $(FAPI_RC): $(TOOLS_ATTR_DIR)/parseErrorInfo.pl $(ERROR_XML_FILES) # The above is commented out as the current version of make produces errors # This was taken from the P8 SBE Makefile which worked. -$(OBJDIR)/fixed.bin: $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin - $(TOOLS_IMAGE_DIR)/sbe_xip_tool $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin extract .fixed $(BASE_OBJDIR)/fixed.bin +$(OBJDIR)/fixed.bin: $(P9_XIP_TOOL) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin + $(P9_XIP_TOOL) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin extract .fixed $(BASE_OBJDIR)/fixed.bin -appendbase: $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin $(OBJDIR)/$(IMAGE_SBE_NAME).bin - $(TOOLS_IMAGE_DIR)/sbe_xip_tool $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin append .base $(OBJDIR)/$(IMAGE_SBE_NAME).bin +appendbase: $(P9_XIP_TOOL) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin $(OBJDIR)/$(IMAGE_SBE_NAME).bin + $(P9_XIP_TOOL) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin append .base $(OBJDIR)/$(IMAGE_SBE_NAME).bin -appendloader: $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin $(OBJDIR)/$(IMAGE_LOADER_NAME).bin - $(TOOLS_IMAGE_DIR)/sbe_xip_tool $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin append .baseloader $(OBJDIR)/$(IMAGE_LOADER_NAME).bin +appendloader: $(P9_XIP_TOOL) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin $(OBJDIR)/$(IMAGE_LOADER_NAME).bin + $(P9_XIP_TOOL) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin append .baseloader $(OBJDIR)/$(IMAGE_LOADER_NAME).bin #/afs/bb/proj/cte/tools/ppetools/prod/powerpc-eabi/bin/objcopy -O binary --only-section=.fixed $(OBJDIR)/$(IMAGE_SEEPROM_NAME).out $(OBJDIR)/fixed.bin @@ -339,6 +345,7 @@ clean: rm -fr $(OBJDIR) rm -f $(TOP-FIXED-HEADERS) $(MAKE) -C $(TOOLS_IMAGE_DIR) -f Makefile clean + $(MAKE) -C $(P9_XIP_SRCDIR) -f Makefile clean rm -f *.dump rm -f hwp_return_codes.H hwp_error_info.H hwp_ffdc_classes.H collect_reg_ffdc.C set_sbe_error.H sbe_build_info.H rm -f $(GEN-CREATEATTRGETSETMACROS) diff --git a/sbe/image/base_loader.c b/sbe/image/base_loader.c index ce47a903..0e67a482 100644 --- a/sbe/image/base_loader.c +++ b/sbe/image/base_loader.c @@ -1,4 +1,4 @@ -#include "sbe_xip_image.h" +#include "p9_xip_image.h" #include "sbetrace.H" int32_t base_loader(); @@ -8,11 +8,11 @@ int32_t base_loader() { int32_t rc = 0; - SbeXipHeader *hdr = 0;//getXipHdr(); + P9XipHeader *hdr = 0;//getXipHdr(); uint32_t idx; - for(idx = 0; idx < SBE_XIP_SECTIONS; idx++) { + for(idx = 0; idx < P9_XIP_SECTIONS; idx++) { hdr++; } diff --git a/sbe/image/base_main.C b/sbe/image/base_main.C index 5ade739c..97a9633b 100644 --- a/sbe/image/base_main.C +++ b/sbe/image/base_main.C @@ -13,7 +13,6 @@ extern "C" { #include "pk.h" #include "pk_trace.h" #include "base_ppe_main.h" -#include "sbe_xip_image.h" } #define KERNEL_STACK_SIZE 256 #define MAIN_THREAD_STACK_SIZE 256 diff --git a/sbe/image/base_ppe_header.S b/sbe/image/base_ppe_header.S index 0f56c532..92fb606b 100644 --- a/sbe/image/base_ppe_header.S +++ b/sbe/image/base_ppe_header.S @@ -7,9 +7,9 @@ /// \file base_ppe_header.S /// \brief code to create header, toc, strings, fixed and fixed_toc sections /// -/// function SbeXipHeader creates header section, function .proc_sbe_fixed +/// function P9XipHeader creates header section, function .proc_sbe_fixed /// creates fixed, fixed_toc sections -#include "sbe_xip_image.h" +#include "p9_xip_image.h" #include "proc_sbe_fixed.H" @@ -62,9 +62,9 @@ .endm -// .macro SbeXipHeader, magic, link_address, entry_point, image_size +// .macro P9XipHeader, magic, link_address, entry_point, image_size - .macro SbeXipSection, s:req, alignment=1, empty=0 + .macro P9XipSection, s:req, alignment=1, empty=0 __\s\()_section: .if \empty .long 0 @@ -78,7 +78,7 @@ __\s\()_section: .endm - .macro SbeXipHeader, magic, link_address, entry_point, image_size + .macro P9XipHeader, magic, link_address, entry_point, image_size .section .header, "a", @progbits @@ -98,29 +98,29 @@ __entry_address_sbe: __header_64_reserved: .quad 0, 0, 0, 0 - .xip_toc magic, SBE_XIP_UINT64, __magic - .xip_toc entry_offset, SBE_XIP_UINT64, __entry_offset - .xip_toc link_address, SBE_XIP_UINT64, __link_address - .xip_toc entry_address_sbe, SBE_XIP_UINT64, __entry_address_sbe + .xip_toc magic, P9_XIP_UINT64, __magic + .xip_toc entry_offset, P9_XIP_UINT64, __entry_offset + .xip_toc link_address, P9_XIP_UINT64, __link_address + .xip_toc entry_address_sbe, P9_XIP_UINT64, __entry_address_sbe ////////////////////////////////////////////////////////////////////// // Section Table - 8-byte aligned; 16 entries; Not TOC-Indexed ////////////////////////////////////////////////////////////////////// - SbeXipSection header - SbeXipSection fixed, 8 - SbeXipSection fixed_toc, 8 - SbeXipSection loader_text, 4 - SbeXipSection loader_data, 8 - SbeXipSection text, 4 - SbeXipSection data, 8 - SbeXipSection toc, 4 - SbeXipSection strings - SbeXipSection base, 4, empty=1 - SbeXipSection baseloader, 8, empty=1 - SbeXipSection overlay, 8, empty=1 - SbeXipSection rings, 8, empty=1 - SbeXipSection hbbl, 8, empty=1 + P9XipSection header + P9XipSection fixed, 8 + P9XipSection fixed_toc, 8 + P9XipSection loader_text, 4 + P9XipSection loader_data, 8 + P9XipSection text, 4 + P9XipSection data, 8 + P9XipSection toc, 4 + P9XipSection strings + P9XipSection base, 4, empty=1 + P9XipSection baseloader, 8, empty=1 + P9XipSection overlay, 8, empty=1 + P9XipSection rings, 8, empty=1 + P9XipSection hbbl, 8, empty=1 ////////////////////////////////////////////////////////////////////// @@ -136,9 +136,9 @@ __build_time: __header_32_reserved: .long 0, 0, 0, 0, 0 - .xip_toc image_size, SBE_XIP_UINT32, __image_size - .xip_toc build_date, SBE_XIP_UINT32, __build_date - .xip_toc build_time, SBE_XIP_UINT32, __build_time + .xip_toc image_size, P9_XIP_UINT32, __image_size + .xip_toc build_date, P9_XIP_UINT32, __build_date + .xip_toc build_time, P9_XIP_UINT32, __build_time ////////////////////////////////////////////////////////////////////// @@ -146,7 +146,7 @@ __header_32_reserved: ////////////////////////////////////////////////////////////////////// __header_version: - .byte SBE_XIP_HEADER_VERSION + .byte P9_XIP_HEADER_VERSION __toc_normalized: .byte 0 __toc_sorted: @@ -154,9 +154,9 @@ __toc_sorted: __header_8_reserved: .byte 0, 0, 0, 0, 0 - .xip_toc header_version, SBE_XIP_UINT8, __header_version - .xip_toc toc_normalized, SBE_XIP_UINT8, __toc_normalized - .xip_toc toc_sorted, SBE_XIP_UINT8, __toc_sorted + .xip_toc header_version, P9_XIP_UINT8, __header_version + .xip_toc toc_normalized, P9_XIP_UINT8, __toc_normalized + .xip_toc toc_sorted, P9_XIP_UINT8, __toc_sorted ////////////////////////////////////////////////////////////////////// @@ -170,8 +170,8 @@ __build_host: __header_string_reserved: .space 24, 0 - .xip_toc build_user, SBE_XIP_STRING, __build_user - .xip_toc build_host, SBE_XIP_STRING, __build_host + .xip_toc build_user, P9_XIP_STRING, __build_user + .xip_toc build_host, P9_XIP_STRING, __build_host .endm @@ -186,7 +186,7 @@ __header_string_reserved: .section .strings, "aS", @progbits ..set_default_space IMAGE_SPACE_SEEPROM - SbeXipHeader SBE_SEEPROM_MAGIC, 0xFFF00000, 0xFFF00C78, _seeprom_size + P9XipHeader P9_SEEPROM_MAGIC, 0xFFF00000, 0xFFF00C78, _seeprom_size // Create the .fixed section .proc_sbe_fixed_system diff --git a/sbe/image/base_sbe_fixed.S b/sbe/image/base_sbe_fixed.S index 496b7e82..eb88482f 100644 --- a/sbe/image/base_sbe_fixed.S +++ b/sbe/image/base_sbe_fixed.S @@ -1,7 +1,7 @@ /// \file sbefixed.S /// \brief code to generated fixed section in pibmem image /// -#include "sbe_xip_image.h" +#include "p9_xip_image.h" #include "proc_sbe_fixed.H" diff --git a/sbe/image/fapi_sbe_common.H b/sbe/image/fapi_sbe_common.H deleted file mode 100644 index 29376c81..00000000 --- a/sbe/image/fapi_sbe_common.H +++ /dev/null @@ -1,47 +0,0 @@ -//----------------------------------------------------------------------------- -// *! (C) Copyright International Business Machines Corp. 2014 -// *! All Rights Reserved -- Property of IBM -// *! *** IBM Confidential *** -//----------------------------------------------------------------------------- - -/// \file fapi_sbe_common.H -/// \brief provides several preprocessor macros used functions in fixed secion. -/// -/// Several preprocessor macros are required to have different definitions in -/// C, C++ and SBE assembly procedures. These common forms are collected here. - -#ifndef __FAPI_SBE_COMMON_H -#define __FAPI_SBE_COMMON_H - -/// Several preprocessor macros are required to have different definitions in -/// C, C++ and SBE assembly procedures. These common forms are collected here. - -#if defined __ASSEMBLER__ - -#define CONST_UINT8_T(name, expr) .set name, (expr) -#define CONST_UINT32_T(name, expr) .set name, (expr) -#define CONST_UINT64_T(name, expr) .set name, (expr) - -#define ULL(x) x - -#elif defined __cplusplus - -#include <stdint.h> - -#define CONST_UINT8_T(name, expr) const uint8_t name = (expr); -#define CONST_UINT32_T(name, expr) const uint32_t name = (expr); -#define CONST_UINT64_T(name, expr) const uint64_t name = (expr); - -#define ULL(x) x##ull - -#else // C code - -// CONST_UINT[8,3,64]_T() can't be used in C code/headers; Use -// -// #define <symbol> <value> [ or ULL(<value>) for 64-bit constants - -#define ULL(x) x##ull - -#endif // __ASSEMBLER__ - -#endif // __FAPI_SBE_COMMON_H diff --git a/sbe/image/img_defs.mk b/sbe/image/img_defs.mk index 5ce99c80..dca2b5cd 100644 --- a/sbe/image/img_defs.mk +++ b/sbe/image/img_defs.mk @@ -70,8 +70,16 @@ ifndef HWPLIB_SRCDIR export HWPLIB_SRCDIR = $(abspath ../../import/chips/p9/procedures/hwp/lib) endif +ifndef P9_XIP_SRCDIR +export P9_XIP_SRCDIR = $(abspath ../../import/chips/p9/xip) +endif + +ifndef P9_XIP_BINDIR +export P9_XIP_BINDIR = $(P9_XIP_SRCDIR)/bin +endif + ifndef IMG_INCLUDES -export IMG_INCLUDES = -I$(IMAGE_SRCDIR) -I$(CACHE_SRCDIR) -I$(CORE_SRCDIR) -I$(PERV_SRCDIR) -I$(NEST_SRCDIR) +export IMG_INCLUDES = -I$(P9_XIP_SRCDIR) -I$(IMAGE_SRCDIR) -I$(CACHE_SRCDIR) -I$(CORE_SRCDIR) -I$(PERV_SRCDIR) -I$(NEST_SRCDIR) endif ifndef BASE_OBJDIR diff --git a/sbe/image/sbe_common.H b/sbe/image/sbe_common.H index 4e48339b..c9745afb 100644 --- a/sbe/image/sbe_common.H +++ b/sbe/image/sbe_common.H @@ -11,7 +11,7 @@ #include "sbe_link.H" -#include "sbe_xip_image.h" +#include "p9_xip_image.h" //#include "sbe_xip_header.H" /// Macros for generating the .fixed section @@ -24,7 +24,7 @@ /// In assembler each invocation also creates space in the .fixed_toc section /// for a fixed TOC entry. Unlike the normal TOC no data is generated for /// .fixed_toc by the data declaration. Instead, the fixed TOC table is -/// filled in during image normalization by normalizeToc (sbe_xip_image.c) +/// filled in during image normalization by normalizeToc (p9_xip_image.c) /// which requires that there be one and only one fixed TOC entery allocated /// per TOC entry referencing the .fixed section. This means that in the /// current implementation it is not possible to create .fixed_toc entries @@ -39,7 +39,7 @@ .byte 0 .endr - .xip_toc \symbol, SBE_XIP_UINT8, \symbol, ((\tnumber)*(\elements)) + .xip_toc \symbol, P9_XIP_UINT8, \symbol, ((\tnumber)*(\elements)) .pushsection .fixed_toc .space 8 @@ -54,7 +54,7 @@ .byte 0 .endr - .xip_toc \symbol, SBE_XIP_INT8, \symbol, ((\tnumber)*(\elements)) + .xip_toc \symbol, P9_XIP_INT8, \symbol, ((\tnumber)*(\elements)) .pushsection .fixed_toc .space 8 @@ -71,7 +71,7 @@ .byte 0,0 .endr - .xip_toc \symbol, SBE_XIP_UINT16, \symbol, ((\tnumber)*(\elements)) + .xip_toc \symbol, P9_XIP_UINT16, \symbol, ((\tnumber)*(\elements)) .pushsection .fixed_toc .space 8 @@ -88,7 +88,7 @@ .byte 0,0 .endr - .xip_toc \symbol, SBE_XIP_INT16, \symbol, ((\tnumber)*(\elements)) + .xip_toc \symbol, P9_XIP_INT16, \symbol, ((\tnumber)*(\elements)) .pushsection .fixed_toc .space 8 @@ -105,7 +105,7 @@ .long 0 .endr - .xip_toc \symbol, SBE_XIP_UINT32, \symbol, ((\tnumber)*(\elements)) + .xip_toc \symbol, P9_XIP_UINT32, \symbol, ((\tnumber)*(\elements)) .pushsection .fixed_toc .space 8 @@ -122,7 +122,7 @@ .long 0 .endr - .xip_toc \symbol, SBE_XIP_INT32, \symbol, ((\tnumber)*(\elements)) + .xip_toc \symbol, P9_XIP_INT32, \symbol, ((\tnumber)*(\elements)) .pushsection .fixed_toc .space 8 @@ -138,7 +138,7 @@ .quad 0 .endr - .xip_toc \symbol, SBE_XIP_UINT64, \symbol, ((\tnumber)*(\elements)) + .xip_toc \symbol, P9_XIP_UINT64, \symbol, ((\tnumber)*(\elements)) .pushsection .fixed_toc .space 8 @@ -154,7 +154,7 @@ .quad 0 .endr - .xip_toc \symbol, SBE_XIP_INT64, \symbol, ((\tnumber)*(\elements)) + .xip_toc \symbol, P9_XIP_INT64, \symbol, ((\tnumber)*(\elements)) .pushsection .fixed_toc .space 8 @@ -167,7 +167,7 @@ \symbol\(): .quadia (\space), (\address) - .xip_toc \symbol, SBE_XIP_UINT64, \symbol + .xip_toc \symbol, P9_XIP_UINT64, \symbol .pushsection .fixed_toc .space 8 diff --git a/sbe/image/sbe_loader.c b/sbe/image/sbe_loader.c index 9f944615..184ead21 100644 --- a/sbe/image/sbe_loader.c +++ b/sbe/image/sbe_loader.c @@ -1,4 +1,4 @@ -#include "sbe_xip_image.h" +#include "p9_xip_image.h" int32_t sbe_loader() __attribute__ ((section (".loader_text"))); @@ -7,11 +7,11 @@ int32_t sbe_loader() { int32_t rc = 0; - SbeXipHeader *hdr = 0;//getXipHdr(); + P9XipHeader *hdr = 0;//getXipHdr(); uint32_t idx; - for(idx = 0; idx < SBE_XIP_SECTIONS; idx++) { + for(idx = 0; idx < P9_XIP_SECTIONS; idx++) { hdr++; } diff --git a/sbe/image/sbe_xip_image.c b/sbe/image/sbe_xip_image.c deleted file mode 100644 index d800650b..00000000 --- a/sbe/image/sbe_xip_image.c +++ /dev/null @@ -1,2460 +0,0 @@ -/// \file sbe_xip_image.c -/// \brief APIs for validating, normalizing, searching and manipulating -/// SBE-XIP images. -/// -/// The background, APIs and implementation details are documented in the -/// document "SBE-XIP Binary format" currently available at this link: -/// -/// - https://mcdoc.boeblingen.de.ibm.com/out/out.ViewDocument.php?documentid=2678 -/// -/// \bug The sbe_xip_validate() API should be carefully reviewed to ensure -/// that validating even a corrupt image can not lead to a segfault, i.e., to -/// ensure that no memory outside of the putative bounds of the image is ever -/// referenced during validation. - -#ifndef PLIC_MODULE -#include <stddef.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#endif // PLIC_MODULE - -#include <stddef.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include "sbe_xip_image.h" - - -//////////////////////////////////////////////////////////////////////////// -// Local Functions -//////////////////////////////////////////////////////////////////////////// - -#ifdef DEBUG_SBE_XIP_IMAGE - -// Debugging support, normally disabled. All of the formatted I/O you see in -// the code is effectively under this switch. - -#ifdef __FAPI - -#include "fapi.H" -#define fprintf(stream, ...) FAPI_ERR(__VA_ARGS__) -#define printf(...) FAPI_INF(__VA_ARGS__) -#define TRACE_NEWLINE "" - -#else // __FAPI - -#include <stdio.h> -#define TRACE_NEWLINE "\n" - -#endif // __FAPI - -// Portable formatting of uint64_t. The ISO C99 standard requires -// __STDC_FORMAT_MACROS to be defined in order for PRIx64 etc. to be defined. - -#define __STDC_FORMAT_MACROS -#include <inttypes.h> - -#define F0x016llx "0x%016" PRIx64 -#define F0x012llx "0x%012" PRIx64 - -XIP_STATIC SBE_XIP_ERROR_STRINGS(sbe_xip_error_strings); - -#define TRACE_ERROR(x) \ - ({ \ - fprintf(stderr, "%s:%d : Returning error code %d : %s" TRACE_NEWLINE, \ - __FILE__, __LINE__, (x), \ - SBE_XIP_ERROR_STRING(sbe_xip_error_strings, (x))); \ - (x); \ - }) - -#define TRACE_ERRORX(x, ...) \ - ({ \ - TRACE_ERROR(x); \ - fprintf(stderr, ##__VA_ARGS__); \ - (x); \ - }) - - -// Uncomment these if required for debugging, otherwise we get warnings from -// GCC as they are not otherwise used. - -#if 0 - -XIP_STATIC uint32_t xipRevLe32(const uint32_t i_x); - -XIP_STATIC SBE_XIP_TYPE_STRINGS(type_strings); - -XIP_STATIC void -dumpToc(int index, SbeXipToc* toc) -{ - printf("TOC entry %d @ %p\n" - " iv_id = 0x%08x\n" - " iv_data = 0x%08x\n" - " iv_type = %s\n" - " iv_section = 0x%02x\n" - " iv_elements = %d\n", - index, toc, - xipRevLe32(toc->iv_id), - xipRevLe32(toc->iv_data), - SBE_XIP_TYPE_STRING(type_strings, toc->iv_type), - toc->iv_section, - toc->iv_elements); -} - -#endif - -#if 0 - -XIP_STATIC void -dumpItem(SbeXipItem* item) -{ - printf("SbeXipItem @ %p\n" - " iv_toc = %p\n" - " iv_address = " F0x016llx "\n" - " iv_imageData = %p\n" - " iv_id = %s\n" - " iv_type = %s\n" - " iv_elements = %d\n", - item, - item->iv_toc, - item->iv_address, - item->iv_imageData, - item->iv_id, - SBE_XIP_TYPE_STRING(type_strings, item->iv_type), - item->iv_elements); - dumpToc(-1, item->iv_toc); -} - -#endif /* 0 */ - -XIP_STATIC void -dumpSectionTable(const void* i_image) -{ - int i, rc; - SbeXipSection section; - - printf("Section table dump of image @ %p\n" - " Entry Offset Size\n" - "-------------------------------\n", - i_image); - - for (i = 0; i < SBE_XIP_SECTIONS; i++) { - rc = sbe_xip_get_section(i_image, i, §ion); - if (rc) { - printf(">>> dumpSectionTable got error at entry %d : %s\n", - i, SBE_XIP_ERROR_STRING(sbe_xip_error_strings, rc)); - break; - } - printf("%7d 0x%08x 0x%08x\n", - i, section.iv_offset, section.iv_size); - } -} - -#else - -#define TRACE_ERROR(x) (x) -#define TRACE_ERRORX(x, ...) (x) -#define dumpToc(...) -#define dumpItem(...) -#define dumpSectionTable(...) - -#endif - - -// Note: For maximum flexibility we provide private versions of -// 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 - -XIP_STATIC uint16_t -xipRevLe16(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 - -XIP_STATIC uint32_t -xipRevLe32(const uint32_t i_x) -{ - uint32_t rx; - -#ifndef _BIG_ENDIAN - uint8_t *pix = (uint8_t*)(&i_x); - uint8_t *prx = (uint8_t*)(&rx); - - prx[0] = pix[3]; - prx[1] = pix[2]; - prx[2] = pix[1]; - prx[3] = pix[0]; -#else - rx = i_x; -#endif - - return rx; -} - - -/// Byte-reverse a 64-bit integer if on a little-endian machine - -XIP_STATIC uint64_t -xipRevLe64(const uint64_t i_x) -{ - uint64_t rx; - -#ifndef _BIG_ENDIAN - uint8_t *pix = (uint8_t*)(&i_x); - uint8_t *prx = (uint8_t*)(&rx); - - prx[0] = pix[7]; - prx[1] = pix[6]; - prx[2] = pix[5]; - prx[3] = pix[4]; - prx[4] = pix[3]; - prx[5] = pix[2]; - prx[6] = pix[1]; - prx[7] = pix[0]; -#else - rx = i_x; -#endif - - return rx; -} - - -/// What is the image link address? - -XIP_STATIC uint64_t -xipLinkAddress(const void* i_image) -{ - return xipRevLe64(((SbeXipHeader*)i_image)->iv_linkAddress); -} - - -/// What is the image size? - -XIP_STATIC uint32_t -xipImageSize(const void* i_image) -{ - return xipRevLe32(((SbeXipHeader*)i_image)->iv_imageSize); -} - - -/// Set the image size - -XIP_STATIC void -xipSetImageSize(void* io_image, const size_t i_size) -{ - ((SbeXipHeader*)io_image)->iv_imageSize = xipRevLe32(i_size); -} - - -/// Re-establish the required final alignment - -XIP_STATIC void -xipFinalAlignment(void* io_image) -{ - uint32_t size; - - size = xipImageSize(io_image); - - if ((size % SBE_XIP_FINAL_ALIGNMENT) != 0) { - xipSetImageSize(io_image, - size + (SBE_XIP_FINAL_ALIGNMENT - - (size % SBE_XIP_FINAL_ALIGNMENT))); - } -} - - -/// Compute a host address from an image address and offset - -XIP_STATIC void* -xipHostAddressFromOffset(const void* i_image, const uint32_t offset) -{ - return (void*)((unsigned long)i_image + offset); -} - - -/// Convert a IMAGE address to a host address - -XIP_STATIC void* -xipImage2Host(const void* i_image, const uint64_t i_imageAddress) -{ - return xipHostAddressFromOffset(i_image, - i_imageAddress - xipLinkAddress(i_image)); -} - - -XIP_STATIC int -xipValidateImageAddress(const void* i_image, - const uint64_t i_imageAddress, - const uint32_t size) -{ - int rc; - - if ((i_imageAddress < xipLinkAddress(i_image)) || - (i_imageAddress > (xipLinkAddress(i_image) + - xipImageSize(i_image) - - size))) { - rc = TRACE_ERRORX(SBE_XIP_INVALID_ARGUMENT, - "The IMAGE address " F0x012llx - " is outside the bounds " - "of the image (" - F0x012llx ":" F0x012llx - ") for %u-byte access.\n", - i_imageAddress, - xipLinkAddress(i_image), - xipLinkAddress(i_image) + xipImageSize(i_image) - 1, - size); - } else { - rc = 0; - } - return rc; -} - - -/// Get the magic number from the image - -XIP_STATIC uint64_t -xipMagic(const void* i_image) -{ - return xipRevLe64(((SbeXipHeader*)i_image)->iv_magic); -} - - -/// Get the header version from the image - -XIP_STATIC uint8_t -xipHeaderVersion(const void* i_image) -{ - return ((SbeXipHeader*)i_image)->iv_headerVersion; -} - - -/// Has the image been normalized? - -XIP_STATIC uint8_t -xipNormalized(const void* i_image) -{ - return ((SbeXipHeader*)i_image)->iv_normalized; -} - - -/// Has the image TOC been sorted? - -XIP_STATIC uint8_t -xipSorted(const void* i_image) -{ - return ((SbeXipHeader*)i_image)->iv_tocSorted; -} - - -/// A quick check that the image exists, has the correct magic and header -/// version, and optionally is normalized. - -XIP_STATIC int -xipQuickCheck(const void* i_image, const int i_normalizationRequired) -{ - int rc; - - do { - rc = 0; - - if (i_image == 0) { - rc = TRACE_ERRORX(SBE_XIP_IMAGE_ERROR, - "Image pointer is NULL (0)\n"); - break; - } - if ((xipMagic(i_image) >> 32) != SBE_XIP_MAGIC) { - rc = TRACE_ERRORX(SBE_XIP_IMAGE_ERROR, - "Magic number mismatch; Found " - "" F0x016llx ", expected 0x%08x........\n", - xipMagic(i_image), SBE_XIP_MAGIC); - break; - } - if ((xipHeaderVersion(i_image)) != SBE_XIP_HEADER_VERSION) { - rc = TRACE_ERRORX(SBE_XIP_IMAGE_ERROR, - "Header version mismatch; Expecting %d, " - "found %d\n", - SBE_XIP_HEADER_VERSION, - xipHeaderVersion(i_image)); - break; - } - if (i_normalizationRequired && !xipNormalized(i_image)) { - rc = TRACE_ERRORX(SBE_XIP_NOT_NORMALIZED, - "Image not normalized\n"); - break; - } - } while(0); - - return rc; -} - - -/// Convert a 32-bit relocatable offset to a full IMAGE 48-bit address - -XIP_STATIC uint64_t -xipFullAddress(const void* i_image, uint32_t offset) -{ - return (xipLinkAddress(i_image) & 0x0000ffff00000000ull) + offset; -} - - -/// Translate a section table entry - -XIP_STATIC void -xipTranslateSection(SbeXipSection* o_dest, const SbeXipSection* i_src) -{ -#ifndef _BIG_ENDIAN - -#if SBE_XIP_HEADER_VERSION != 8 -#error This code assumes the SBE-XIP header version 8 layout -#endif - - o_dest->iv_offset = xipRevLe32(i_src->iv_offset); - o_dest->iv_size = xipRevLe32(i_src->iv_size); - o_dest->iv_alignment = i_src->iv_alignment; - o_dest->iv_reserved8[0] = 0; - o_dest->iv_reserved8[1] = 0; - o_dest->iv_reserved8[2] = 0; -#else - if (o_dest != i_src) { - *o_dest = *i_src; - } -#endif /* _BIG_ENDIAN */ -} - - -/// Translate a TOC entry - -XIP_STATIC void -xipTranslateToc(SbeXipToc* o_dest, SbeXipToc* i_src) -{ -#ifndef _BIG_ENDIAN - -#if SBE_XIP_HEADER_VERSION != 8 -#error This code assumes the SBE-XIP header version 8 layout -#endif - - o_dest->iv_id = xipRevLe32(i_src->iv_id); - o_dest->iv_data = xipRevLe32(i_src->iv_data); - o_dest->iv_type = i_src->iv_type; - o_dest->iv_section = i_src->iv_section; - o_dest->iv_elements = i_src->iv_elements; - o_dest->iv_pad = 0; -#else - if (o_dest != i_src) { - *o_dest = *i_src; - } -#endif /* _BIG_ENDIAN */ -} - - -/// Find the final (highest-address) section of the image - -XIP_STATIC int -xipFinalSection(const void* i_image, int* o_sectionId) -{ - int i, rc, found; - uint32_t offset; - SbeXipHeader hostHeader; - - sbe_xip_translate_header(&hostHeader, (SbeXipHeader*)i_image); - - found = 0; - offset = 0; - *o_sectionId = 0; /* Make GCC -O3 happy */ - for (i = 0; i < SBE_XIP_SECTIONS; i++) { - if ((hostHeader.iv_section[i].iv_size != 0) && - (hostHeader.iv_section[i].iv_offset >= offset)) { - *o_sectionId = i; - offset = hostHeader.iv_section[i].iv_offset; - found = 1; - } - } - if (!found) { - rc = TRACE_ERRORX(SBE_XIP_IMAGE_ERROR, "The image is empty\n"); - } else { - rc = 0; - } - return rc; -} - - -/// Return a pointer to an image-format section table entry - -XIP_STATIC int -xipGetSectionPointer(const void* i_image, - const int i_sectionId, - SbeXipSection** o_imageSection) -{ - int rc; - - if ((i_sectionId < 0) || (i_sectionId >= SBE_XIP_SECTIONS)) { - rc = TRACE_ERROR(SBE_XIP_INVALID_ARGUMENT); - } else { - *o_imageSection = - &(((SbeXipHeader*)i_image)->iv_section[i_sectionId]); - rc = 0; - } - return rc; -} - - -/// Restore a section table entry from host format to image format. - -XIP_STATIC int -xipPutSection(const void* i_image, - const int i_sectionId, - SbeXipSection* i_hostSection) -{ - int rc; - SbeXipSection *imageSection; - - rc = xipGetSectionPointer(i_image, i_sectionId, &imageSection); - - if (!rc) { - xipTranslateSection(imageSection, i_hostSection); - } - - return rc; -} - - -/// Set the offset of a section - -XIP_STATIC int -xipSetSectionOffset(void* io_image, const int i_section, - const uint32_t i_offset) -{ - SbeXipSection* section; - int rc; - - rc = xipGetSectionPointer(io_image, i_section, §ion); - if (!rc) { - section->iv_offset = xipRevLe32(i_offset); - } - return rc; -} - - -/// Set the size of a section - -XIP_STATIC int -xipSetSectionSize(void* io_image, const int i_section, const uint32_t i_size) -{ - SbeXipSection* section; - int rc; - - rc = xipGetSectionPointer(io_image, i_section, §ion); - if (!rc) { - section->iv_size = xipRevLe32(i_size); - } - return rc; -} - - -/// Translate a IMAGE address in the image to a section and offset - -// We first check to be sure that the IMAGE address is contained in the image, -// using the full 48-bit form. Then we scan the section table to see which -// section contains the address - if none then the image is corrupted. We can -// (must) use the 32-bit offset form of the address here. - -XIP_STATIC int -xipImage2Section(const void* i_image, - const uint64_t i_imageAddress, - int* o_section, - uint32_t* o_offset) -{ - int rc, sectionId; - SbeXipSection section; - uint32_t addressOffset; - - do { - rc = 0; - - if ((i_imageAddress < xipLinkAddress(i_image)) || - (i_imageAddress > - (xipLinkAddress(i_image) + xipImageSize(i_image)))) { - rc = TRACE_ERRORX(SBE_XIP_INVALID_ARGUMENT, - "image2section: The i_imageAddress argument " - "(" F0x016llx ")\nis outside the bounds of the " - "image (" F0x016llx ":" F0x016llx ")\n", - i_imageAddress, - xipLinkAddress(i_image), - xipLinkAddress(i_image) + xipImageSize(i_image)); - break; - } - - addressOffset = (i_imageAddress - xipLinkAddress(i_image)) & 0xffffffff; - - for (sectionId = 0; sectionId < SBE_XIP_SECTIONS; sectionId++) { - rc = sbe_xip_get_section(i_image, sectionId, §ion); - if (rc) { - rc = TRACE_ERROR(SBE_XIP_BUG); /* Can't happen */ - break; - } - if ((section.iv_size != 0) && - (addressOffset >= section.iv_offset) && - (addressOffset < (section.iv_offset + section.iv_size))) { - break; - } - } - if (rc) break; - - if (sectionId == SBE_XIP_SECTIONS) { - rc = TRACE_ERRORX(SBE_XIP_IMAGE_ERROR, - "Error processing IMAGE address " F0x016llx ". " - "The address is not mapped in any section.\n" - "A section table dump appears below\n", - i_imageAddress); - dumpSectionTable(i_image); - break; - } - - *o_section = sectionId; - *o_offset = addressOffset - section.iv_offset; - - } while(0); - - return rc; -} - - -/// Get the information required to search the TOC. -/// -/// All return values are optional. - -XIP_STATIC int -xipGetToc(void* i_image, - SbeXipToc** o_toc, - size_t* o_entries, - int* o_sorted, - char** o_strings) -{ - int rc; - SbeXipSection tocSection, stringsSection; - - do { - rc = sbe_xip_get_section(i_image, SBE_XIP_SECTION_TOC, &tocSection); - if (rc) break; - - rc = sbe_xip_get_section(i_image, SBE_XIP_SECTION_STRINGS, - &stringsSection); - if (rc) break; - - if (o_toc) { - *o_toc = (SbeXipToc*)((uint8_t*)i_image + tocSection.iv_offset); - } - if (o_entries) { - *o_entries = tocSection.iv_size / sizeof(SbeXipToc); - } - if (o_sorted) { - *o_sorted = xipSorted(i_image); - } - if (o_strings) { - *o_strings = (char*)i_image + stringsSection.iv_offset; - } - } while (0); - return rc; -} - - -/// Compare two normalized TOC entries for sorting. - -XIP_STATIC int -xipCompareToc(const SbeXipToc* i_a, const SbeXipToc* i_b, - const char* i_strings) -{ - return strcmp(i_strings + xipRevLe32(i_a->iv_id), - i_strings + xipRevLe32(i_b->iv_id)); -} - - -/// Iterative quicksort of the TOC - -// Note: The stack requirement is limited to 256 bytes + minor local storage. - -XIP_STATIC void -xipQuickSort(SbeXipToc* io_toc, int i_left, int i_right, - const char* i_strings) -{ - int i, j, left, right, sp; - SbeXipToc pivot, temp; - uint32_t stack[64]; - - sp = 0; - stack[sp++] = i_left; - stack[sp++] = i_right; - - while (sp) { - - right = stack[--sp]; - left = stack[--sp]; - - i = left; - j = right; - - pivot = io_toc[(i + j) / 2]; - - while (i <= j) { - while (xipCompareToc(&(io_toc[i]), &pivot, i_strings) < 0) { - i++; - } - while (xipCompareToc(&(io_toc[j]), &pivot, i_strings) > 0) { - j--; - } - if (i <= j) { - temp = io_toc[i]; - io_toc[i] = io_toc[j]; - io_toc[j] = temp; - i++; - j--; - } - } - if (left < j) { - stack[sp++] = left; - stack[sp++] = j; - } - if (i < right) { - stack[sp++] = i; - stack[sp++] = right; - } - } -} - - -/// TOC linear search - -XIP_STATIC int -xipLinearSearch(void* i_image, const char* i_id, SbeXipToc** o_entry) -{ - int rc; - SbeXipToc *imageToc, hostToc; - size_t entries; - char* strings; - - *o_entry = 0; - rc = xipGetToc(i_image, &imageToc, &entries, 0, &strings); - if (!rc) { - for (; entries; entries--, imageToc++) { - xipTranslateToc(&hostToc, imageToc); - if (strcmp(i_id, strings + hostToc.iv_id) == 0) { - break; - } - } - if (entries) { - *o_entry = imageToc; - rc = 0; - } else { - *o_entry = 0; - rc = TRACE_ERROR(SBE_XIP_ITEM_NOT_FOUND); - } - } - return rc; -} - - -/// A classic binary search of a (presumed) sorted array - -XIP_STATIC int -xipBinarySearch(void* i_image, const char* i_id, SbeXipToc** o_entry) -{ - int rc; - SbeXipToc *imageToc; - size_t entries; - char* strings; - int sorted, left, right, next, sort; - - do { - *o_entry = 0; - - rc = xipGetToc(i_image, &imageToc, &entries, &sorted, &strings); - if (rc) break; - - if (!sorted) { - rc = TRACE_ERROR(SBE_XIP_BUG); - break; - } - - left = 0; - right = entries - 1; - while (left <= right) { - next = (left + right) / 2; - sort = strcmp(i_id, strings + xipRevLe32(imageToc[next].iv_id)); - if (sort == 0) { - *o_entry = &(imageToc[next]); - break; - } else if (sort < 0) { - right = next - 1; - } else { - left = next + 1; - } - } - if (*o_entry == 0) { - rc = TRACE_ERROR(SBE_XIP_ITEM_NOT_FOUND); - break; - } - } while (0); - return rc; -} - - -/// Validate a TOC entry as a mapping function -/// -/// The TOC is validated by searching for the entry, which will uncover -/// duplicate entries or problems with sorting/searching. - -XIP_STATIC int -xipValidateTocEntry(void* io_image, const SbeXipItem* i_item, void* io_arg) -{ - int rc; - SbeXipItem found; - - do { - rc = sbe_xip_find(io_image, i_item->iv_id, &found); - if (rc) { - rc = TRACE_ERRORX(rc, "TOC entry for %s not found\n", - i_item->iv_id); - } else if (found.iv_toc != i_item->iv_toc) { - rc = TRACE_ERRORX(SBE_XIP_TOC_ERROR, - "Duplicate TOC entry for '%s'\n", i_item->iv_id); - } - break; - } while (0); - return rc; -} - - -// 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 -xipHash32(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 -// addresses in the TOC are actually 32-bit offsets in the address space named -// in bits 16:31 of the link address of the image. - -XIP_STATIC int -xipNormalizeToc(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 { - - // Translate the TOC entry to host format. Then locate the - // sections/offsets of the Id string (which must be in .strings) and - // the data. - - xipTranslateToc(&hostToc, io_imageToc); - - hostString = - (char*)xipImage2Host(io_image, - xipFullAddress(io_image, hostToc.iv_id)); - - rc = xipImage2Section(io_image, - xipFullAddress(io_image, hostToc.iv_id), - &idSection, - &idOffset); - if (rc) break; - - if (idSection != SBE_XIP_SECTION_STRINGS) { - rc = TRACE_ERROR(SBE_XIP_IMAGE_ERROR); - break; - } - - rc = xipImage2Section(io_image, - xipFullAddress(io_image, hostToc.iv_data), - &dataSection, - &dataOffset); - if (rc) break; - - // Now replace the Id and data pointers with their offsets, and update - // the data section in the TOC entry. - - hostToc.iv_id = idOffset; - 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 = xipRevLe32(xipHash32(hostString)); - (*io_fixedTocEntry)->iv_offset = xipRevLe16(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 - - xipTranslateToc(io_imageToc, &hostToc); - - } while (0); - - return rc; -} - - -// Check for hash collisions in the .fixed mini-TOC. Note that endianness is -// not an issue here, as we're comparing for equality. - -XIP_STATIC int -xipHashCollision(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 - -XIP_STATIC int -xipDecodeToc(void* i_image, - SbeXipToc* i_imageToc, - SbeXipItem* o_item) -{ - int rc; - SbeXipToc hostToc; - SbeXipSection dataSection, stringsSection; - - do { - if (!xipNormalized(i_image)) { - rc = TRACE_ERROR(SBE_XIP_NOT_NORMALIZED); - break; - } - - - // Translate the TOC entry and set the TOC pointer, data type and - // number of elements in the outgoing structure. The Id string is - // always located in the TOC_STRINGS section. - - xipTranslateToc(&hostToc, i_imageToc); - - o_item->iv_toc = i_imageToc; - o_item->iv_type = hostToc.iv_type; - o_item->iv_elements = hostToc.iv_elements; - - sbe_xip_get_section(i_image, SBE_XIP_SECTION_STRINGS, &stringsSection); - o_item->iv_id = - (char*)i_image + stringsSection.iv_offset + hostToc.iv_id; - - - // The data (or text address) are addressed by relative offsets from - // the beginning of their section. The TOC entry may remain in the TOC - // even though the section has been removed from the image, so this - // case needs to be covered. - - rc = sbe_xip_get_section(i_image, hostToc.iv_section, &dataSection); - if (rc) break; - - if (dataSection.iv_size == 0) { - rc = TRACE_ERROR(SBE_XIP_DATA_NOT_PRESENT); - break; - } - - o_item->iv_imageData = - (void*)((uint8_t*)i_image + - dataSection.iv_offset + hostToc.iv_data); - - o_item->iv_address = - xipLinkAddress(i_image) + dataSection.iv_offset + hostToc.iv_data; - - o_item->iv_partial = 0; - - } while (0); - return rc; -} - - -/// Sort the TOC - -XIP_STATIC int -xipSortToc(void* io_image) -{ - int rc; - SbeXipToc *hostToc; - size_t entries; - char* strings; - - do { - rc = xipQuickCheck(io_image, 1); - if (rc) break; - - if (xipSorted(io_image)) break; - - rc = xipGetToc(io_image, &hostToc, &entries, 0, &strings); - if (rc) break; - - xipQuickSort(hostToc, 0, entries - 1, strings); - - ((SbeXipHeader*)io_image)->iv_tocSorted = 1; - - } while (0); - - return rc; -} - - -// Pad the image with 0 to a given power-of-2 alignment. The image size is -// modified to reflect the pad, but the caller must modify the section size to -// reflect the pad. - -XIP_STATIC int -xipPadImage(void* io_image, uint32_t i_allocation, - uint32_t i_align, uint32_t* pad) -{ - int rc; - - do { - rc = 0; - - if ((i_align == 0) || ((i_align & (i_align - 1)) != 0)) { - rc = TRACE_ERRORX(SBE_XIP_INVALID_ARGUMENT, - "Alignment specification (%u) " - "not a power-of-2\n", - i_align); - break; - } - - *pad = xipImageSize(io_image) % i_align; - if (*pad != 0) { - *pad = i_align - *pad; - - if ((xipImageSize(io_image) + *pad) > i_allocation) { - rc = TRACE_ERROR(SBE_XIP_WOULD_OVERFLOW); - break; - } - - memset((void*)((unsigned long)io_image + xipImageSize(io_image)), - 0, *pad); - xipSetImageSize(io_image, xipImageSize(io_image) + *pad); - } - } while (0); - - return rc; -} - - -// Get the .fixed_toc section - -XIP_STATIC int -xipGetFixedToc(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, §ion); - 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. - -XIP_STATIC int -xipFixedFind(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 = xipGetFixedToc(i_image, &toc, &entries); - if (rc) break; - - for (hash = xipRevLe32(xipHash32(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 xipDecodeToc() - // 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 + xipRevLe16(toc->iv_offset); - - o_item->iv_imageData = (void*)((uint8_t*)i_image + offset); - o_item->iv_address = xipLinkAddress(i_image) + offset; - - } while (0); - - return rc; -} - - -// Search for an item in the special built-in TOC of header fields, and -// populate a partial TOC entry if requested. -// -// This facility was added to allow header data to be searched by name even -// when the TOC has been stripped. This API will only be used in the case of a -// stripped TOC since the header fields are also indexed in the main TOC. -// -// The table is allocated on the stack in order to make this code concurrently -// patchable in PHYP (although PHYP applications will never use this code). -// The table is small and unsorted so a linear search is adequate, and the -// stack requirememts are small. - -XIP_STATIC int -xipHeaderFind(void* i_image, const char* i_id, SbeXipItem* o_item) -{ - int rc; - unsigned i; - uint32_t offset; - SbeXipSection headerSection; - -#define HEADER_TOC(id, field, type) \ - {#id, offsetof(SbeXipHeader, field), type} - - struct HeaderToc { - - const char* iv_id; - uint16_t iv_offset; - uint8_t iv_type; - - } toc[] = { - - HEADER_TOC(magic, iv_magic, SBE_XIP_UINT64), - HEADER_TOC(entry_offset, iv_entryOffset, SBE_XIP_UINT64), - HEADER_TOC(link_address, iv_linkAddress, SBE_XIP_UINT64), - - HEADER_TOC(image_size, iv_imageSize, SBE_XIP_UINT32), - HEADER_TOC(build_date, iv_buildDate, SBE_XIP_UINT32), - HEADER_TOC(build_time, iv_buildTime, SBE_XIP_UINT32), - - HEADER_TOC(header_version, iv_headerVersion, SBE_XIP_UINT8), - HEADER_TOC(toc_normalized, iv_normalized, SBE_XIP_UINT8), - HEADER_TOC(toc_sorted, iv_tocSorted, SBE_XIP_UINT8), - - HEADER_TOC(build_user, iv_buildUser, SBE_XIP_STRING), - HEADER_TOC(build_host, iv_buildHost, SBE_XIP_STRING), - - }; - - do { - - rc = SBE_XIP_ITEM_NOT_FOUND; - for (i = 0; i < (sizeof(toc) / sizeof(struct HeaderToc)); i++) { - if (strcmp(i_id, toc[i].iv_id) == 0) { - rc = 0; - break; - } - } - - if (rc) break; - - // 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 xipDecodeToc() - // 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[i].iv_type; - o_item->iv_elements = 1; /* True for now... */ - - rc = sbe_xip_get_section(i_image, SBE_XIP_SECTION_HEADER, - &headerSection); - if (rc) break; - - if (headerSection.iv_size == 0) { - rc = TRACE_ERROR(SBE_XIP_DATA_NOT_PRESENT); - break; - } - - offset = headerSection.iv_offset + toc[i].iv_offset; - - o_item->iv_imageData = (void*)((uint8_t*)i_image + offset); - o_item->iv_address = xipLinkAddress(i_image) + offset; - - } while (0); - - return rc; -} - - -//////////////////////////////////////////////////////////////////////////// -// Published API -//////////////////////////////////////////////////////////////////////////// - -int -sbe_xip_validate(void* i_image, const uint32_t i_size) -{ - SbeXipHeader hostHeader; - int rc = 0, i; - uint32_t linkAddress, imageSize, extent, offset, size; - uint8_t alignment; - - sbe_xip_translate_header(&hostHeader, (SbeXipHeader*)i_image); - - do { - - // Validate C/Assembler constraints. - - if (sizeof(SbeXipSection) != SIZE_OF_SBE_XIP_SECTION) { - rc = TRACE_ERRORX(SBE_XIP_BUG, - "C/Assembler size mismatch(%d/%d) " - "for SbeXipSection\n", - sizeof(SbeXipSection), SIZE_OF_SBE_XIP_SECTION); - break; - } - - if (sizeof(SbeXipToc) != SIZE_OF_SBE_XIP_TOC) { - rc = TRACE_ERRORX(SBE_XIP_BUG, - "C/Assembler size mismatch(%d/%d) " - "for SbeXipToc\n", - sizeof(SbeXipToc), SIZE_OF_SBE_XIP_TOC); - 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 = xipQuickCheck(i_image, 0); - if (rc) break; - - // Validate the image size - - linkAddress = hostHeader.iv_linkAddress; - imageSize = hostHeader.iv_imageSize; - extent = linkAddress + imageSize; - - if (imageSize < sizeof(SbeXipHeader)) { - rc = TRACE_ERRORX(SBE_XIP_IMAGE_ERROR, - "sbe_xip_validate(%p, %u) : " - "The image size recorded in the image " - "(%u) is smaller than the header size.\n", - i_image, i_size, imageSize); - break; - } - if (imageSize != i_size) { - rc = TRACE_ERRORX(SBE_XIP_IMAGE_ERROR, - "sbe_xip_validate(%p, %u) : " - "The image size recorded in the image " - "(%u) does not match the i_size parameter.\n", - i_image, i_size, imageSize); - break; - } - if (extent <= linkAddress) { - rc = TRACE_ERRORX(SBE_XIP_IMAGE_ERROR, - "sbe_xip_validate(%p, %u) : " - "Given the link address (%u) and the " - "image size, the image wraps the address space\n", - i_image, i_size, linkAddress); - break; - } - if ((imageSize % SBE_XIP_FINAL_ALIGNMENT) != 0) { - rc = TRACE_ERRORX(SBE_XIP_ALIGNMENT_ERROR, - "sbe_xip_validate(%p, %u) : " - "The image size (%u) is not a multiple of %u\n", - i_image, i_size, imageSize, - SBE_XIP_FINAL_ALIGNMENT); - break; - } - - // Validate that all sections appear to be within the image - // bounds, and are aligned correctly. - - for (i = 0; i < SBE_XIP_SECTIONS; i++) { - - offset = hostHeader.iv_section[i].iv_offset; - size = hostHeader.iv_section[i].iv_size; - alignment = hostHeader.iv_section[i].iv_alignment; - - if ((offset > imageSize) || - ((offset + size) > imageSize) || - ((offset + size) < offset)) { - rc = TRACE_ERRORX(SBE_XIP_IMAGE_ERROR, - "Section %d does not appear to be within " - "the bounds of the image\n" - "offset = %u, size = %u, image size = %u\n", - i, offset, size, imageSize); - break; - } - if ((offset % alignment) != 0) { - rc = TRACE_ERRORX(SBE_XIP_ALIGNMENT_ERROR, - "Section %d requires %d-byte initial " - "alignment but the section offset is %u\n", - i, alignment, offset); - break; - } - } - if (rc) break; - - // If the TOC exists and the image is normalized, validate each TOC - // entry. - - size = hostHeader.iv_section[SBE_XIP_SECTION_TOC].iv_size; - if (size != 0) { - if (xipNormalized(i_image)) { - rc = sbe_xip_map_toc(i_image, xipValidateTocEntry, 0); - if (rc) break; - } - } - } while (0); - return rc; -} - - -int -sbe_xip_validate2(void* i_image, const uint32_t i_size, const uint32_t i_maskIgnores) -{ - SbeXipHeader hostHeader; - int rc = 0, i; - uint32_t linkAddress, imageSize, extent, offset, size; - uint8_t alignment; - - sbe_xip_translate_header(&hostHeader, (SbeXipHeader*)i_image); - - do { - - // Validate C/Assembler constraints. - - if (sizeof(SbeXipSection) != SIZE_OF_SBE_XIP_SECTION) { - rc = TRACE_ERRORX(SBE_XIP_BUG, - "C/Assembler size mismatch(%d/%d) " - "for SbeXipSection\n", - sizeof(SbeXipSection), SIZE_OF_SBE_XIP_SECTION); - break; - } - - if (sizeof(SbeXipToc) != SIZE_OF_SBE_XIP_TOC) { - rc = TRACE_ERRORX(SBE_XIP_BUG, - "C/Assembler size mismatch(%d/%d) " - "for SbeXipToc\n", - sizeof(SbeXipToc), SIZE_OF_SBE_XIP_TOC); - 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 = xipQuickCheck(i_image, 0); - if (rc) break; - - // Validate the image size - - linkAddress = hostHeader.iv_linkAddress; - imageSize = hostHeader.iv_imageSize; - extent = linkAddress + imageSize; - - if (imageSize < sizeof(SbeXipHeader)) { - rc = TRACE_ERRORX(SBE_XIP_IMAGE_ERROR, - "sbe_xip_validate2(%p, %u) : " - "The image size recorded in the image " - "(%u) is smaller than the header size.\n", - i_image, i_size, imageSize); - break; - } - if (imageSize != i_size && !(i_maskIgnores & SBE_XIP_IGNORE_FILE_SIZE)) { - rc = TRACE_ERRORX(SBE_XIP_IMAGE_ERROR, - "sbe_xip_validate2(%p, %u) : " - "The image size recorded in the image " - "(%u) does not match the i_size parameter.\n", - i_image, i_size, imageSize); - break; - } - if (extent <= linkAddress) { - rc = TRACE_ERRORX(SBE_XIP_IMAGE_ERROR, - "sbe_xip_validate2(%p, %u) : " - "Given the link address (%u) and the " - "image size, the image wraps the address space\n", - i_image, i_size, linkAddress); - break; - } - if ((imageSize % SBE_XIP_FINAL_ALIGNMENT) != 0) { - rc = TRACE_ERRORX(SBE_XIP_ALIGNMENT_ERROR, - "sbe_xip_validate2(%p, %u) : " - "The image size (%u) is not a multiple of %u\n", - i_image, i_size, imageSize, - SBE_XIP_FINAL_ALIGNMENT); - break; - } - - // Validate that all sections appear to be within the image - // bounds, and are aligned correctly. - - for (i = 0; i < SBE_XIP_SECTIONS; i++) { - - offset = hostHeader.iv_section[i].iv_offset; - size = hostHeader.iv_section[i].iv_size; - alignment = hostHeader.iv_section[i].iv_alignment; - - if ((offset > imageSize) || - ((offset + size) > imageSize) || - ((offset + size) < offset)) { - rc = TRACE_ERRORX(SBE_XIP_IMAGE_ERROR, - "Section %d does not appear to be within " - "the bounds of the image\n" - "offset = %u, size = %u, image size = %u\n", - i, offset, size, imageSize); - break; - } - if ((offset % alignment) != 0) { - rc = TRACE_ERRORX(SBE_XIP_ALIGNMENT_ERROR, - "Section %d requires %d-byte initial " - "alignment but the section offset is %u\n", - i, alignment, offset); - break; - } - } - if (rc) break; - - // If the TOC exists and the image is normalized, validate each TOC - // entry. - - size = hostHeader.iv_section[SBE_XIP_SECTION_TOC].iv_size; - if (size != 0) { - if (xipNormalized(i_image)) { - rc = sbe_xip_map_toc(i_image, xipValidateTocEntry, 0); - if (rc) break; - } - } - } while (0); - return rc; -} - - -// Normalization: -// -// 1. Normalize the TOC, unless the image is already normalized. The image -// must be marked as normalized before sorting. -// -// 2. Sort the TOC. -// -// 3. Clear the section offsets of any empty sections to make the section -// table reports less confusing. -// -// 4. Clear normalization status on any failure. - -int -sbe_xip_normalize(void* io_image) -{ - int rc, i; - SbeXipSection section; - SbeXipToc* imageToc; - SbeXipHashedToc* fixedImageToc; - SbeXipHashedToc* fixedTocEntry; - size_t tocEntries, fixedTocEntries, fixedEntriesRemaining; - - do { - rc = xipQuickCheck(io_image, 0); - if (rc) break; - - if (!xipNormalized(io_image)) { - - rc = xipGetToc(io_image, &imageToc, &tocEntries, 0, 0); - if (rc) break; - - rc = xipGetFixedToc(io_image, &fixedImageToc, &fixedTocEntries); - if (rc) break; - - fixedTocEntry = fixedImageToc; - fixedEntriesRemaining = fixedTocEntries; - - for (; tocEntries--; imageToc++) { - rc = xipNormalizeToc(io_image, imageToc, - &fixedTocEntry, &fixedEntriesRemaining); - if (rc) break; - - } - if (rc) break; - - if (fixedEntriesRemaining != 0) { - rc = TRACE_ERRORX(SBE_XIP_TOC_ERROR, - "Not enough TOC entries for .fixed"); - break; - } - - rc = xipHashCollision(fixedImageToc, fixedTocEntries); - if (rc) break; - - ((SbeXipHeader*)io_image)->iv_normalized = 1; - } - - rc = xipSortToc(io_image); - if (rc) break; - - for (i = 0; i < SBE_XIP_SECTIONS; i++) { - rc = sbe_xip_get_section(io_image, i, §ion); - if (rc) break; - if (section.iv_size == 0) { - xipSetSectionOffset(io_image, i, 0); - } - } - if (rc) break; - - } while(0); - - ((SbeXipHeader*)io_image)->iv_normalized = (rc == 0); - - return rc; -} - - -int -sbe_xip_image_size(void* io_image, uint32_t* o_size) -{ - int rc; - - rc = xipQuickCheck(io_image, 0); - if (!rc) { - *o_size = xipImageSize(io_image); - } - return rc; -} - - -int -sbe_xip_get_section(const void* i_image, - const int i_sectionId, - SbeXipSection* o_hostSection) -{ - int rc; - SbeXipSection *imageSection; - - rc = xipGetSectionPointer(i_image, i_sectionId, &imageSection); - - if (!rc) { - xipTranslateSection(o_hostSection, imageSection); - } - - return rc; -} - - -// If the 'big' TOC is not present, search the mini-TOCs that only index the -// .fixed and .header sections. - -int -sbe_xip_find(void* i_image, - const char* i_id, - SbeXipItem* o_item) -{ - int rc; - SbeXipToc* toc; - SbeXipItem item, *pitem; - SbeXipSection* tocSection; - - do { - rc = xipQuickCheck(i_image, 1); - if (rc) break; - - rc = xipGetSectionPointer(i_image, SBE_XIP_SECTION_TOC, &tocSection); - if (rc) break; - - if (tocSection->iv_size == 0) { - rc = xipFixedFind(i_image, i_id, o_item); - if (rc) { - rc = xipHeaderFind(i_image, i_id, o_item); - } - break; - } - - if (xipSorted(i_image)) { - rc = xipBinarySearch(i_image, i_id, &toc); - } else { - rc = xipLinearSearch(i_image, i_id, &toc); - } - if (rc) break; - - if (o_item) { - pitem = o_item; - } else { - pitem = &item; - } - rc = xipDecodeToc(i_image, toc, pitem); - if (rc) break; - - } while (0); - - return rc; -} - - - - -int -sbe_xip_get_scalar(void *i_image, const char* i_id, uint64_t* o_data) -{ - int rc; - SbeXipItem item; - - rc = sbe_xip_find(i_image, i_id, &item); - if (!rc) { - switch (item.iv_type) { - case SBE_XIP_UINT8: - *o_data = *((uint8_t*)(item.iv_imageData)); - break; - case SBE_XIP_UINT16: - *o_data = xipRevLe16(*((uint16_t*)(item.iv_imageData))); - break; - case SBE_XIP_UINT32: - *o_data = xipRevLe32(*((uint32_t*)(item.iv_imageData))); - break; - case SBE_XIP_UINT64: - *o_data = xipRevLe64(*((uint64_t*)(item.iv_imageData))); - break; - case SBE_XIP_INT8: - *o_data = *((int8_t*)(item.iv_imageData)); - break; - case SBE_XIP_INT16: - *o_data = xipRevLe16(*((int16_t*)(item.iv_imageData))); - break; - case SBE_XIP_INT32: - *o_data = xipRevLe32(*((int32_t*)(item.iv_imageData))); - break; - case SBE_XIP_INT64: - *o_data = xipRevLe64(*((int64_t*)(item.iv_imageData))); - break; - case SBE_XIP_ADDRESS: - *o_data = item.iv_address; - break; - default: - rc = TRACE_ERROR(SBE_XIP_TYPE_ERROR); - break; - } - } - return rc; -} - - -int -sbe_xip_get_element(void *i_image, - const char* i_id, - const uint32_t i_index, - uint64_t* o_data) -{ - int rc; - SbeXipItem item; - - do { - rc = sbe_xip_find(i_image, i_id, &item); - if (rc) break; - - if ((item.iv_elements != 0) && (i_index >= item.iv_elements)) { - rc = TRACE_ERROR(SBE_XIP_BOUNDS_ERROR); - break; - } - - switch (item.iv_type) { - case SBE_XIP_UINT8: - *o_data = ((uint8_t*)(item.iv_imageData))[i_index]; - break; - case SBE_XIP_UINT16: - *o_data = xipRevLe16(((uint16_t*)(item.iv_imageData))[i_index]); - break; - case SBE_XIP_UINT32: - *o_data = xipRevLe32(((uint32_t*)(item.iv_imageData))[i_index]); - break; - case SBE_XIP_UINT64: - *o_data = xipRevLe64(((uint64_t*)(item.iv_imageData))[i_index]); - break; - case SBE_XIP_INT8: - *o_data = ((int8_t*)(item.iv_imageData))[i_index]; - break; - case SBE_XIP_INT16: - *o_data = xipRevLe16(((int16_t*)(item.iv_imageData))[i_index]); - break; - case SBE_XIP_INT32: - *o_data = xipRevLe32(((int32_t*)(item.iv_imageData))[i_index]); - break; - case SBE_XIP_INT64: - *o_data = xipRevLe64(((int64_t*)(item.iv_imageData))[i_index]); - break; - default: - rc = TRACE_ERROR(SBE_XIP_TYPE_ERROR); - break; - } - if (rc) break; - - } while (0); - return rc; -} - - -int -sbe_xip_get_string(void *i_image, const char* i_id, char** o_data) -{ - int rc; - SbeXipItem item; - - rc = sbe_xip_find(i_image, i_id, &item); - if (!rc) { - switch (item.iv_type) { - case SBE_XIP_STRING: - *o_data = (char*)(item.iv_imageData); - break; - default: - rc = TRACE_ERROR(SBE_XIP_TYPE_ERROR); - break; - } - } - return rc; -} - - -int -sbe_xip_read_uint64(const void *i_image, - const uint64_t i_imageAddress, - uint64_t* o_data) -{ - int rc; - - do { - rc = xipQuickCheck(i_image, 0); - if (rc) break; - - rc = xipValidateImageAddress(i_image, i_imageAddress, 8); - if (rc) break; - - if (i_imageAddress % 8) { - rc = TRACE_ERROR(SBE_XIP_ALIGNMENT_ERROR); - break; - } - - *o_data = - xipRevLe64(*((uint64_t*)xipImage2Host(i_image, i_imageAddress))); - - } while(0); - - return rc; -} - - -int -sbe_xip_set_scalar(void* io_image, const char* i_id, const uint64_t i_data) -{ - int rc; - SbeXipItem item; - - rc = sbe_xip_find(io_image, i_id, &item); - if (!rc) { - switch(item.iv_type) { - case SBE_XIP_UINT8: - *((uint8_t*)(item.iv_imageData)) = (uint8_t)i_data; - break; - case SBE_XIP_UINT16: - *((uint16_t*)(item.iv_imageData)) = xipRevLe16((uint16_t)i_data); - break; - case SBE_XIP_UINT32: - *((uint32_t*)(item.iv_imageData)) = xipRevLe32((uint32_t)i_data); - break; - case SBE_XIP_UINT64: - *((uint64_t*)(item.iv_imageData)) = xipRevLe64((uint64_t)i_data); - break; - case SBE_XIP_INT8: - *((int8_t*)(item.iv_imageData)) = (int8_t)i_data; - break; - case SBE_XIP_INT16: - *((int16_t*)(item.iv_imageData)) = xipRevLe16((int16_t)i_data); - break; - case SBE_XIP_INT32: - *((int32_t*)(item.iv_imageData)) = xipRevLe32((int32_t)i_data); - break; - case SBE_XIP_INT64: - *((int64_t*)(item.iv_imageData)) = xipRevLe64((int64_t)i_data); - break; - default: - rc = TRACE_ERROR(SBE_XIP_TYPE_ERROR); - break; - } - } - return rc; -} - - -int -sbe_xip_set_element(void *i_image, - const char* i_id, - const uint32_t i_index, - const uint64_t i_data) -{ - int rc; - SbeXipItem item; - - do { - rc = sbe_xip_find(i_image, i_id, &item); - if (rc) break; - - if ((item.iv_elements != 0) && (i_index >= item.iv_elements)) { - rc = TRACE_ERROR(SBE_XIP_BOUNDS_ERROR); - break; - } - - switch (item.iv_type) { - case SBE_XIP_UINT8: - ((uint8_t*)(item.iv_imageData))[i_index] = (uint8_t)i_data; - break; - case SBE_XIP_UINT16: - ((uint16_t*)(item.iv_imageData))[i_index] = - xipRevLe16((uint16_t)i_data); - break; - case SBE_XIP_UINT32: - ((uint32_t*)(item.iv_imageData))[i_index] = - xipRevLe32((uint32_t)i_data); - break; - case SBE_XIP_UINT64: - ((uint64_t*)(item.iv_imageData))[i_index] = - xipRevLe64((uint64_t)i_data); - break; - case SBE_XIP_INT8: - ((int8_t*)(item.iv_imageData))[i_index] = (int8_t)i_data; - break; - case SBE_XIP_INT16: - ((int16_t*)(item.iv_imageData))[i_index] = - xipRevLe16((uint16_t)i_data); - break; - case SBE_XIP_INT32: - ((int32_t*)(item.iv_imageData))[i_index] = - xipRevLe32((uint32_t)i_data); - break; - case SBE_XIP_INT64: - ((int64_t*)(item.iv_imageData))[i_index] = - xipRevLe64((uint64_t)i_data); - break; - default: - rc = TRACE_ERROR(SBE_XIP_TYPE_ERROR); - break; - } - if (rc) break; - - } while (0); - - return rc; -} - - -int -sbe_xip_set_string(void *i_image, const char* i_id, const char* i_data) -{ - int rc; - SbeXipItem item; - char* dest; - - rc = sbe_xip_find(i_image, i_id, &item); - if (!rc) { - switch (item.iv_type) { - case SBE_XIP_STRING: - dest = (char*)(item.iv_imageData); - if (strlen(dest) < strlen(i_data)) { - memcpy(dest, i_data, strlen(dest)); - } else { - strcpy(dest, i_data); - } - break; - default: - rc = TRACE_ERROR(SBE_XIP_TYPE_ERROR); - break; - } - } - return rc; -} - - -int -sbe_xip_write_uint64(void *io_image, - const uint64_t i_imageAddress, - const uint64_t i_data) -{ - int rc; - - do { - rc = xipQuickCheck(io_image, 0); - if (rc) break; - - rc = xipValidateImageAddress(io_image, i_imageAddress, 8); - if (rc) break; - - if (i_imageAddress % 8) { - rc = TRACE_ERROR(SBE_XIP_ALIGNMENT_ERROR); - break; - } - - *((uint64_t*)xipImage2Host(io_image, i_imageAddress)) = - xipRevLe64(i_data); - - } while(0); - - return rc; -} - - -int -sbe_xip_delete_section(void* io_image, const int i_sectionId) -{ - int rc, final; - SbeXipSection section; - - do { - rc = xipQuickCheck(io_image, 1); - if (rc) break; - - rc = sbe_xip_get_section(io_image, i_sectionId, §ion); - if (rc) break; - - - // Deleting an empty section is a NOP. Otherwise the section must be - // the final section of the image. Update the sizes and re-establish - // the final image alignment. - - if (section.iv_size == 0) break; - - rc = xipFinalSection(io_image, &final); - if (rc) break; - - if (final != i_sectionId) { - rc = TRACE_ERRORX(SBE_XIP_SECTION_ERROR, - "Attempt to delete non-final section %d\n", - i_sectionId); - break; - } - - xipSetSectionOffset(io_image, i_sectionId, 0); - xipSetSectionSize(io_image, i_sectionId, 0); - - - // For cleanliness we also remove any alignment padding that had been - // appended between the now-last section and the deleted section, then - // re-establish the final alignment. The assumption is that all images - // always have the correct final alignment, so there is no way this - // could overflow a designated buffer space since the image size is - // the same or has been reduced. - - rc = xipFinalSection(io_image, &final); - if (rc) break; - - rc = sbe_xip_get_section(io_image, final, §ion); - if (rc) break; - - xipSetImageSize(io_image, section.iv_offset + section.iv_size); - xipFinalAlignment(io_image); - - } while (0); - - return rc; -} - - -#ifndef PPC_HYP - -// This API is not needed by PHYP procedures, and is elided since PHYP does -// not support malloc(). - -int -sbe_xip_duplicate_section(const void* i_image, - const int i_sectionId, - void** o_duplicate, - uint32_t* o_size) -{ - SbeXipSection section; - int rc; - - *o_duplicate = 0; - - do { - rc = xipQuickCheck(i_image, 0); - if (rc) break; - - rc = sbe_xip_get_section(i_image, i_sectionId, §ion); - if (rc) break; - - if (section.iv_size == 0) { - rc = TRACE_ERRORX(SBE_XIP_SECTION_ERROR, - "Attempt to duplicate empty section %d\n", - i_sectionId); - break; - } - - *o_duplicate = malloc(section.iv_size); - *o_size = section.iv_size; - - if (*o_duplicate == 0) { - rc = TRACE_ERROR(SBE_XIP_NO_MEMORY); - break; - } - - memcpy(*o_duplicate, - xipHostAddressFromOffset(i_image, section.iv_offset), - section.iv_size); - - - } while (0); - - if (rc) { - free(*o_duplicate); - *o_duplicate = 0; - *o_size = 0; - } - - return rc; -} - -#endif // PPC_HYP - - -// The append must be done in such a way that if the append fails, the image -// is not modified. This behavior is required by applications that -// speculatively append until the allocation fails, but still require the -// final image to be valid. To accomplish this the initial image size and -// section statistics are captured at entry, and restored in the event of an -// error. - -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) -{ - SbeXipSection section, initialSection; - int rc, final, restoreOnError; - void* hostAddress; - uint32_t pad, initialSize; - - do { - restoreOnError = 0; - - rc = xipQuickCheck(io_image, 1); - if (rc) break; - - rc = sbe_xip_get_section(io_image, i_sectionId, §ion); - if (rc) break; - - if (i_size == 0) break; - - initialSection = section; - initialSize = xipImageSize(io_image); - restoreOnError = 1; - - if (section.iv_size == 0) { - - // The section is empty, and now becomes the final section. Pad - // the image to the specified section alignment. Note that the - // size of the previously final section does not change. - - rc = xipPadImage(io_image, i_allocation, section.iv_alignment, - &pad); - if (rc) break; - section.iv_offset = xipImageSize(io_image); - - } else { - - // Otherwise, the section must be the final section in order to - // continue. Remove any padding from the image. - - rc = xipFinalSection(io_image, &final); - if (rc) break; - - if (final != i_sectionId) { - rc = TRACE_ERRORX(SBE_XIP_SECTION_ERROR, - "Attempt to append to non-final section " - "%d\n", i_sectionId); - break; - } - xipSetImageSize(io_image, section.iv_offset + section.iv_size); - } - - - // Make sure the allocated space won't overflow. Set the return - // parameter o_sectionOffset and copy the new data into the image (or - // simply clear the space). - - if ((xipImageSize(io_image) + i_size) > i_allocation) { - rc = TRACE_ERROR(SBE_XIP_WOULD_OVERFLOW); - break; - } - if (o_sectionOffset != 0) { - *o_sectionOffset = section.iv_size; - } - - hostAddress = - xipHostAddressFromOffset(io_image, xipImageSize(io_image)); - if (i_data == 0) { - memset(hostAddress, 0, i_size); - } else { - memcpy(hostAddress, i_data, i_size); - } - - - // Update the image size and section table. Note that the final - // alignment may push out of the allocation. - - xipSetImageSize(io_image, xipImageSize(io_image) + i_size); - xipFinalAlignment(io_image); - - if (xipImageSize(io_image) > i_allocation) { - rc = TRACE_ERROR(SBE_XIP_WOULD_OVERFLOW); - break; - } - - section.iv_size += i_size; - - if (xipPutSection(io_image, i_sectionId, §ion) != 0) { - rc = TRACE_ERROR(SBE_XIP_BUG); /* Can't happen */ - break; - } - - - // Special case - - if (i_sectionId == SBE_XIP_SECTION_TOC) { - ((SbeXipHeader*)io_image)->iv_tocSorted = 0; - } - - } while (0); - - if (rc && restoreOnError) { - if (xipPutSection(io_image, i_sectionId, &initialSection) != 0) { - rc = TRACE_ERROR(SBE_XIP_BUG); /* Can't happen */ - } - xipSetImageSize(io_image, initialSize); - } - - return rc; -} - - -int -sbe_xip_section2image(const void* i_image, - const int i_sectionId, - const uint32_t i_offset, - uint64_t* o_imageAddress) -{ - int rc; - SbeXipSection section; - - do { - rc = xipQuickCheck(i_image, 0); - if (rc) break; - - rc = sbe_xip_get_section(i_image, i_sectionId, §ion); - if (rc) break; - - if (section.iv_size == 0) { - rc = TRACE_ERROR(SBE_XIP_SECTION_ERROR); - break; - } - - if (i_offset > (section.iv_offset + section.iv_size)) { - rc = TRACE_ERROR(SBE_XIP_INVALID_ARGUMENT); - break; - } - - *o_imageAddress = xipLinkAddress(i_image) + section.iv_offset + i_offset; - - if (*o_imageAddress % 4) { - rc = TRACE_ERROR(SBE_XIP_ALIGNMENT_ERROR); - break; - } - - } while(0); - - return rc; -} - - -int -sbe_xip_image2section(const void* i_image, - const uint64_t i_imageAddress, - int* i_section, - uint32_t* i_offset) -{ - int rc; - - do { - rc = xipQuickCheck(i_image, 0); - if (rc) break; - - rc = xipImage2Section(i_image, i_imageAddress, i_section, i_offset); - - } while(0); - - return rc; -} - - -int -sbe_xip_image2host(const void* i_image, - const uint64_t i_imageAddress, - void** o_hostAddress) -{ - int rc; - - do { - rc = xipQuickCheck(i_image, 0); - if (rc) break; - - if ((i_imageAddress < xipLinkAddress(i_image)) || - (i_imageAddress > - (xipLinkAddress(i_image) + xipImageSize(i_image)))) { - rc = TRACE_ERROR(SBE_XIP_INVALID_ARGUMENT); - break; - } - - *o_hostAddress = - xipHostAddressFromOffset(i_image, - i_imageAddress - xipLinkAddress(i_image)); - } while(0); - - return rc; -} - - -int -sbe_xip_host2image(const void* i_image, - void* i_hostAddress, - uint64_t* o_imageAddress) -{ - int rc; - - do { - rc = xipQuickCheck(i_image, 0); - if (rc) break; - - if ((i_hostAddress < i_image) || - (i_hostAddress > - xipHostAddressFromOffset(i_image, xipImageSize(i_image)))) { - rc = TRACE_ERROR(SBE_XIP_INVALID_ARGUMENT); - break; - } - - *o_imageAddress = xipLinkAddress(i_image) + - ((unsigned long)i_hostAddress - (unsigned long)i_image); - if (*o_imageAddress % 4) { - rc = TRACE_ERROR(SBE_XIP_ALIGNMENT_ERROR); - break; - } - } while(0); - - return rc; -} - - -void -sbe_xip_translate_header(SbeXipHeader* o_dest, const SbeXipHeader* i_src) -{ -#ifndef _BIG_ENDIAN - int i; - SbeXipSection* destSection; - const SbeXipSection* srcSection; - -#if SBE_XIP_HEADER_VERSION != 8 -#error This code assumes the SBE-XIP header version 8 layout -#endif - - o_dest->iv_magic = xipRevLe64(i_src->iv_magic); - o_dest->iv_entryOffset = xipRevLe64(i_src->iv_entryOffset); - o_dest->iv_linkAddress = xipRevLe64(i_src->iv_linkAddress); - - for (i = 0; i < 5; i++) { - o_dest->iv_reserved64[i] = 0; - } - - for (i = 0, destSection = o_dest->iv_section, - srcSection = i_src->iv_section; - i < SBE_XIP_SECTIONS; - i++, destSection++, srcSection++) { - xipTranslateSection(destSection, srcSection); - } - - o_dest->iv_imageSize = xipRevLe32(i_src->iv_imageSize); - o_dest->iv_buildDate = xipRevLe32(i_src->iv_buildDate); - o_dest->iv_buildTime = xipRevLe32(i_src->iv_buildTime); - - for (i = 0; i < 5; i++) { - o_dest->iv_reserved32[i] = 0; - } - - o_dest->iv_headerVersion = i_src->iv_headerVersion; - o_dest->iv_normalized = i_src->iv_normalized; - o_dest->iv_tocSorted = i_src->iv_tocSorted; - - for (i = 0; i < 3; i++) { - o_dest->iv_reserved8[i] = 0; - } - - memcpy(o_dest->iv_buildUser, i_src->iv_buildUser, - sizeof(i_src->iv_buildUser)); - memcpy(o_dest->iv_buildHost, i_src->iv_buildHost, - sizeof(i_src->iv_buildHost)); - memcpy(o_dest->iv_reservedChar, i_src->iv_reservedChar, - sizeof(i_src->iv_reservedChar)); - -#else - if (o_dest != i_src) { - *o_dest = *i_src; - } -#endif /* _BIG_ENDIAN */ -} - - -int -sbe_xip_map_toc(void* io_image, - int (*i_fn)(void* io_image, - const SbeXipItem* i_item, - void* io_arg), - void* io_arg) -{ - int rc; - SbeXipToc *imageToc; - SbeXipItem item; - size_t entries; - - do { - rc = xipQuickCheck(io_image, 0); - if (rc) break; - - rc = xipGetToc(io_image, &imageToc, &entries, 0, 0); - if (rc) break; - - for (; entries--; imageToc++) { - rc = xipDecodeToc(io_image, imageToc, &item); - if (rc) break; - rc = i_fn(io_image, &item, io_arg); - if (rc) break; - } - } while(0); - - return rc; -} diff --git a/sbe/image/sbe_xip_image.h b/sbe/image/sbe_xip_image.h deleted file mode 100644 index b295a569..00000000 --- a/sbe/image/sbe_xip_image.h +++ /dev/null @@ -1,1724 +0,0 @@ -//----------------------------------------------------------------------------- -// *! (C) Copyright International Business Machines Corp. 2014 -// *! All Rights Reserved -- Property of IBM -// *! *** IBM Confidential *** -//----------------------------------------------------------------------------- - -/// \file sbe_xip_image.h -/// \brief definition of structs in sections -/// -/// Contains struct ProcSbeFixed which contains functions, rings and -/// attributes whose pointers are stored in the fixed and fixed_toc section -/// Everything related to creating and manipulating SBE-XIP binary images - -#ifndef __SBE_XIP_IMAGE_H -#define __SBE_XIP_IMAGE_H - -#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.H. -*- - -#define SBE_XIP_SECTION_HEADER 0 -#define SBE_XIP_SECTION_FIXED 1 -#define SBE_XIP_SECTION_FIXED_TOC 2 -#define SBE_XIP_SECTION_LOADER_TEXT 3 -#define SBE_XIP_SECTION_LOADER_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_BASE 9 -#define SBE_XIP_SECTION_BASELOADER 10 -#define SBE_XIP_SECTION_OVERLAYS 11 -#define SBE_XIP_SECTION_RINGS 12 -#define SBE_XIP_SECTION_HBBL 13 - -#define SBE_XIP_SECTIONS 14 - -/// @} - - -/// \defgroup sbe_xip_validate() ignore masks. -/// -/// These defines, when matched in sbe_xip_validate(), cause the validation -/// to skip the check of the corresponding property. The purpose is to more -/// effectively debug images that may be damaged and which have excess info -/// before or after the image. The latter will be the case when dumping the -/// image as a memory block without knowing where the image starts and ends. -/// -/// @{ - -#define SBE_XIP_IGNORE_FILE_SIZE (uint32_t)0x00000001 -#define SBE_XIP_IGNORE_ALL (uint32_t)0x80000000 - -/// @} - - -#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", \ - ".loader_text", \ - ".loader_data", \ - ".text", \ - ".data", \ - ".toc", \ - ".strings", \ - ".base", \ - ".baseloader", \ - ".overlays", \ - ".rings", \ - ".hbbl", \ - } - -/// 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 16-bit unsigned integer -#define SBE_XIP_UINT16 0x02 - -/// Data is a 32-bit unsigned integer -#define SBE_XIP_UINT32 0x03 - -/// Data is a 64-bit unsigned integer -#define SBE_XIP_UINT64 0x04 - -/// Data is a single signed byte -#define SBE_XIP_INT8 0x05 - -/// Data is a 16-bit signed integer -#define SBE_XIP_INT16 0x06 - -/// Data is a 32-bit signed integer -#define SBE_XIP_INT32 0x07 - -/// Data is a 64-bit signed integer -#define SBE_XIP_INT64 0x08 - -/// Data is a 0-byte terminated ASCII string -#define SBE_XIP_STRING 0x09 - -/// Data is an address -#define SBE_XIP_ADDRESS 0x0A - -/// The maximum type number -#define SBE_XIP_MAX_TYPE_INDEX 0x0A - -/// 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_UINT16", \ - "SBE_XIP_UINT32", \ - "SBE_XIP_UINT64", \ - "SBE_XIP_INT8", \ - "SBE_XIP_INT16", \ - "SBE_XIP_INT32", \ - "SBE_XIP_INT64", \ - "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 ", \ - "u16", \ - "u32", \ - "u64", \ - "i8 ", \ - "i16", \ - "i32", \ - "i64", \ - "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. -/// -/// images are required to be multiples of 8 bytes in length, to -/// gaurantee that the something 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 image and the applications using SBE-XIP images have strict - /// alignment/padding requirements. The image 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. image images are also required to be - /// multiples of 8 bytes in length, to gaurantee that the something 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. image 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 image 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 image - /// address - uint64_t iv_linkAddress; - - /// The entry address of base loader - uint64_t iv_entryAddressSBE; - - /// Reserved for future expansion - uint64_t iv_reserved64[4]; - - ////////////////////////////////////////////////////////////////////// - // 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 image 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 image 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; - - -/// 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 -/// -/// \param[in] i_maskIgnores Array of ignore bits representing which properties -/// should not be checked for in sbe_xip_validate2(). -/// -/// 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); - -int -sbe_xip_validate2(void* i_image, const uint32_t i_size, const uint32_t i_maskIgnores); - - -/// 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 image -/// 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 image 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_imageAddress A relocatable IMAGE address contained in the -/// image, presumably of an 8-byte data area. The \a i_imageAddress 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_imageAddress. -/// -/// This API is provided for applications that need to manipulate SBE-XIP -/// images in terms of their relocatable IMAGE addresses. The API checks that -/// the \a i_imageAddress is properly aligned and contained in the image, then -/// reads the contents of \a i_imageAddress 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_imageAddress, - 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 IMAGE addresses are considered a -/// scalar type for sbe_xip_get_scalar(), IMAGE 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,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 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 IMAGE 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_imageAddress A relocatable IMAGE address contained in the -/// image, presumably of an 8-byte data area. The \a i_imageAddress 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_imageAddress. -/// -/// This API is provided for applications that need to manipulate SBE-XIP -/// images in terms of their relocatable IMAGE addresses. The API checks that -/// the \a i_imageAddress is properly aligned and contained in the image, then -/// updates the contents of \a i_imageAddress 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_imageAddress, - 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. -/// -/// \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 -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); - - - -/// Delete a section from an SBE-XIP image 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 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. Any alignment padding of the now-last section is also -/// removed. -/// -/// \note 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); - - -#ifndef PPC_HYP - -/// 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 \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 \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 -/// -/// \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* o_size); - -#endif // PPC_HYP - - -/// 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 return value -/// is invalid in the event of a non-0 return code. -/// -/// 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 IMAGE addresses obtained -/// via sbe_xip_section2image(), 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 IMAGE hardware -/// relocation to work, however the APIs don't require this 4K alignment for -/// in-memory manipulation of images. Images to be executed on ImageVe will -/// normally require at least 8-byte final aligment in order to guarantee that -/// the ImageVe 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. -/// -/// \note If the call fails for any reason (other than a bug in the API -/// itself) then the \a io_image data is returned unmodified. -/// -/// \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 IMAGE 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_imageAddress The equivalent relocatable IMAGE address is -/// returned via this pointer. Since valid IMAGE 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 IMAGE -/// 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 IMAGE addresses. -/// -/// \retval 0 Success -/// -/// \retval non-0 See \ref sbe_xip_image_errors -int -sbe_xip_section2image(const void* i_image, - const int i_sectionId, - const uint32_t i_offset, - uint64_t* o_imageAddress); - - -/// Convert an SBE-XIP relocatable image address to a host memory address -/// -/// \param[in] i_image A pointer to an SBE-XIP image in host memory. -/// -/// \param[in] i_imageAddress A relocatable image 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_imageAddress. 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 image 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_imageAddress 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_image2host(const void* i_image, - const uint64_t i_imageAddress, - void** o_hostAddress); - - -/// Convert an SBE-XIP relocatable image address to section Id and offset -/// -/// \param[in] i_image A pointer to an SBE-XIP image in host memory. -/// -/// \param[in] i_imageAddress A relocatable image 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_imageAddress. 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_imageAddress -/// 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 image 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_imageAddress 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_image2section(const void* i_image, - const uint64_t i_imageAddress, - int* o_section, - uint32_t* o_offset); - - -/// Convert an in-memory SBE-XIP host address to a relocatable image 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_imageAddress The API updates the location pointed to by \a -/// o_imageAddress with the equivelent relocatable image address of the memory -/// addressed by i_hostAddress. Since valid image 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 image -/// 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 image 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_host2image(const void* i_image, - void* i_hostAddress, - uint64_t* o_imageAddress); - - - -// PHYP has their own way of implementing the <string.h> functions. PHYP also -// does not allow static functions or data, so all of the XIP_STATIC functions -// defined here are global to PHYP. - -#ifdef PPC_HYP - -#ifdef PLIC_MODULE - -#define strcpy(dest, src) hvstrcpy(dest, src) -#define strlen(s) hvstrlen(s) -#define strcmp(s1, s2) hvstrcmp(s1, s2) -#endif //PLIC_MODULE - -#define XIP_STATIC - -#else // PPC_HYP - -// #define XIP_STATIC static -#define XIP_STATIC - -#endif // PPC_HYP - -// Note: For maximum flexibility we provide private versions of -// 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 -XIP_STATIC uint16_t -xipRevLe16(const uint16_t i_x); - -/// Byte-reverse a 32-bit integer if on a little-endian machine -XIP_STATIC uint32_t -xipRevLe32(const uint32_t i_x); - - -/// Byte-reverse a 64-bit integer if on a little-endian machine -XIP_STATIC uint64_t -xipRevLe64(const uint64_t i_x); - -/// \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 image 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 image 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/tools/image/Makefile b/tools/image/Makefile index 9a015590..b946acd4 100644 --- a/tools/image/Makefile +++ b/tools/image/Makefile @@ -20,6 +20,9 @@ $(warning CTEPATH not defined; defaulting to awd) CTEPATH = /afs/awd/projects/cte endif +P9_XIP_SRCDIR = $(abspath ../../import/chips/p9/xip) +P9_XIP_BINDIR = $(P9_XIP_SRCDIR)/bin + # Locations of required headers. INCLUDES += -I. -I../../ -I../../utils INCLUDES += -I ../../sbe/image/ @@ -34,6 +37,7 @@ INCLUDES += -I ../../pk/std/ INCLUDES += -I ../../pk/trace/ INCLUDES += -I ../../tools/ppetracepp/ INCLUDES += -I ../../import/hwpf/fapi2/include/ +INCLUDES += -I ../../import/chips/p9/xip/ # Under Linux the scheme is to use a common compiler to create procedures. # However, the common compiler can be VERY slow, so if the system compiler is @@ -57,10 +61,9 @@ CC = gcc CXX = g++ endif -#UTILITIES-SOURCES += ../../sbe/image/sbe_xip_image.c -UTILITIES-SOURCES = sbe_xip_tool.c sbe_default_tool.c +UTILITIES-SOURCES = sbe_default_tool.c -UTILITIES = sbe_xip_tool sbe_default_tool +UTILITIES = sbe_default_tool # Utility targets UTILITIES-OBJc = $(patsubst %.c,bin/%.o,$(UTILITIES-SOURCES)) @@ -75,21 +78,18 @@ utilities: buildBinDir $(UTILITIES-EXECUTABLES) buildBinDir: mkdir -p bin -bin/%.o: %.c - $(CXX) -std=c++11 $(INCLUDES) $(CXXFLAGS) -DDEBUG_SBE_XIP_IMAGE=1 -DFAPI2_NO_FFDC -c -o $@ $< +# Build the P9-XIP image code +$(P9_XIP_BINDIR)/p9_xip_image.o: + $(MAKE) -I $(P9_XIP_SRCDIR) -C $(P9_XIP_SRCDIR) -f Makefile -bin/sbe_xip_image.o: ../../sbe/image/sbe_xip_image.c +bin/%.o: %.c $(CXX) -std=c++11 $(INCLUDES) $(CXXFLAGS) -DDEBUG_SBE_XIP_IMAGE=1 -DFAPI2_NO_FFDC -c -o $@ $< -bin/sbe_xip_tool: bin/sbe_xip_image.o bin/p9_ring_identification.o bin/sbe_xip_tool.o - $(CXX) $(CXXFLAGS) ${INCLUDES} -o $@ $^ - ln -sf bin/sbe_xip_tool sbe_xip_tool - -bin/sbe_default_tool: bin/sbe_xip_image.o bin/sbe_default_tool.o +bin/sbe_default_tool: $(P9_XIP_BINDIR)/p9_xip_image.o bin/sbe_default_tool.o $(CXX) $(CXXFLAGS) ${INCLUDES} -o $@ $^ ln -sf bin/sbe_default_tool sbe_default_tool clean: - rm -f sbe_xip_tool sbe_default_tool + rm -f sbe_default_tool rm -rf bin mkdir -p bin diff --git a/tools/image/p9_image_help_base.H b/tools/image/p9_image_help_base.H deleted file mode 100644 index ff5ce70b..00000000 --- a/tools/image/p9_image_help_base.H +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef _P9_IMAGE_HELP_BASE_H_ -#define _P9_IMAGE_HELP_BASE_H_ - -#include <sbe_xip_image.h> - -// -// Various image/ring buffer sizes. Must be used by all users (VBU, FSP, HB, HBI, Cronus) -// -const uint32_t MAX_REF_IMAGE_SIZE = 5000000; // Max reference image size. -const uint32_t FIXED_SEEPROM_WORK_SPACE= 128*1024; // Max work space for Seeprom img. -const uint32_t MAX_SEEPROM_IMAGE_SIZE = 56*1024; // Max Seeprom image size. -const uint32_t FIXED_RING_BUF_SIZE = 60000; // Fixed ring buf size for _fixed. - -const uint8_t MAX_VPD_TYPES = 2; // #G and #R, so far. -#define CHIPLET_ID_MIN 0x00 -#define CHIPLET_ID_MAX 0x1F -#define CHIPLET_ID_EX_MIN 0x10 -#define CHIPLET_ID_EX_MAX 0x1F -const uint8_t MAX_CHIPLETS = CHIPLET_ID_MAX-CHIPLET_ID_MIN+1; -const uint32_t ASM_RS4_LAUNCH_BUF_SIZE = 24; // Byte size of RS4 launch buffer. -const uint32_t WF_ENCAP_SIZE = 400; // Byte size of WF encapsulation. - // (Actually, only 304B but may change.) -const uint32_t WF_WORST_CASE_SIZE_FAC = 4; // WC WF size = 3x ring length. - // (Assumes 12B per write.) - // (4x w/waits instructions.) -const uint32_t LISTING_STRING_SIZE = 256; -const uint64_t MAX_UINT64_T = (uint64_t)0xFFFFFFFF<<32 | (uint64_t)0xFFFFFFFF; - -const uint8_t RING_SECTION_ID[] = { - SBE_XIP_SECTION_RINGS, - SBE_XIP_SECTION_OVERLAYS, -}; -const uint8_t RING_SECTION_ID_SIZE = sizeof(RING_SECTION_ID) / sizeof(RING_SECTION_ID[0]); - -#ifdef __cplusplus -extern "C" { -#endif - -// Base (shared) ring layout for both RS4 and Wiggle-flip layouts. -typedef struct { - uint64_t entryOffset; - uint64_t backItemPtr; - uint32_t sizeOfThis; - uint32_t sizeOfMeta; // Exact size of meta data. Arbitrary size. Not null terminated. -} BaseRingLayout; - -// RS4 specific layout. -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; -} Rs4RingLayout; - -// PairingInfo is used for pairing, or matching, a back pointer address of a -// ring block with its corresponding TOC name. -typedef struct { - uint64_t address; // (in) Holds HOMER backPtr addr of the ring - uint8_t vectorpos; // (in) Vector position of fwdPtr [0;31] - // max=0 for most VPD rings - // max=1 for all non-VPD rings - // max=1 for perv_ VPD rings - // max=15 for most VPD ex_ rings - // max=31 for 16 ex_ chiplets with override - char *name; // (out) TOC name - uint8_t isvpd; // (out) 0: Non-VPD ring 1: VPD ring - uint8_t overridable; // (out) 0: No (most VPD rings) 1: Yes (all non-VPD rings) - uint8_t override; // (out) 0: base 1: override -} PairingInfo; - - -/// -/// **************************************************************************** -/// Function declares. -/// **************************************************************************** -/// -int over_write_ring_data_in_image( void *io_image, - const char *i_ringName, - const void *i_ringData, // WF or RS4 - const uint32_t i_sizeRingData, // Byte size - const uint8_t i_idxVector, - const uint8_t i_override, - const uint8_t i_overridable ); - - -#ifdef __cplusplus -} -#endif - -#endif //_P8_IMAGE_HELP_BASE_H_ diff --git a/tools/image/p9_ring_identification.H b/tools/image/p9_ring_identification.H deleted file mode 100644 index e6ab8745..00000000 --- a/tools/image/p9_ring_identification.H +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef _P9_RING_IDENT_H_ -#define _P9_RING_IDENT_H_ -#include <stddef.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> - - -// Ring ID list structure. -typedef struct { - const char *ringName; - uint8_t ringId; - uint8_t chipIdMin; // the min chipletId - uint8_t chipIdMax; // the max chipletId - const char *ringNameImg; // Ring name in image: ringName + "_ring" - uint8_t vpdKeyword; - uint8_t bWcSpace; // 0: fitted 1: worst-case space (3 x ring length) -} RingIdList; - -extern const RingIdList RING_ID_LIST_PG[], RING_ID_LIST_PR[]; -extern const uint32_t RING_ID_LIST_PG_SIZE, RING_ID_LIST_PR_SIZE; -extern const RingIdList RING_ID_LIST[]; -extern const uint32_t RING_ID_LIST_SIZE; - -// Enumerated VPD keyword values. -// Note! This is DIFFERENT from the MvpdKeyword list in fapiMvpdAccess.H which -// can't be used in this file since it's not, per se, a fapi file. So -// these values need to be translated in xip_customize when passing the -// mvpdKeyword to getMvpdRing(); -enum VpdKeyword { - VPD_KEYWORD_PDG, - VPD_KEYWORD_PDR, - NUM_OF_VPD_TYPES -}; - -int get_vpd_ring_list_entry(const char *i_ringName, - const uint8_t i_ringId, - RingIdList **i_ringIdList); - - -#endif diff --git a/tools/image/p9_ring_identification.c b/tools/image/p9_ring_identification.c deleted file mode 100644 index 0ee5797a..00000000 --- a/tools/image/p9_ring_identification.c +++ /dev/null @@ -1,122 +0,0 @@ -#include <p9_ring_identification.H> - -const RingIdList RING_ID_LIST_PG[] = { - /* ringName ringId chipletId ringNameImg mvpdKeyword wc */ - /* min max */ - {"ab_gptr_ab", 0xA0, 0x08, 0x08, "ab_gptr_ab_ring", VPD_KEYWORD_PDG, 0}, - {"ab_gptr_ioa", 0xA1, 0x08, 0x08, "ab_gptr_ioa_ring", VPD_KEYWORD_PDG, 0}, - {"ab_gptr_perv", 0xA2, 0x08, 0x08, "ab_gptr_perv_ring", VPD_KEYWORD_PDG, 0}, - {"ab_gptr_pll", 0xA3, 0x08, 0x08, "ab_gptr_pll_ring", VPD_KEYWORD_PDG, 0}, - {"ab_time", 0xA4, 0x08, 0x08, "ab_time_ring", VPD_KEYWORD_PDG, 0}, - {"ex_gptr_core", 0xA5, 0xFF, 0xFF, "ex_gptr_core_ring", VPD_KEYWORD_PDG, 0}, //Chip specific - {"ex_gptr_dpll", 0xA6, 0xFF, 0xFF, "ex_gptr_dpll_ring", VPD_KEYWORD_PDG, 0}, //Chip specific - {"ex_gptr_l2", 0xA7, 0xFF, 0xFF, "ex_gptr_l2_ring", VPD_KEYWORD_PDG, 0}, //Chip specific - {"ex_gptr_l3", 0xA8, 0xFF, 0xFF, "ex_gptr_l3_ring", VPD_KEYWORD_PDG, 0}, //Chip specific - {"ex_gptr_l3refr", 0xA9, 0xFF, 0xFF, "ex_gptr_l3refr_ring", VPD_KEYWORD_PDG, 0}, //Chip specific - {"ex_gptr_perv", 0xAA, 0xFF, 0xFF, "ex_gptr_perv_ring", VPD_KEYWORD_PDG, 0}, //Chip specific - {"ex_time_core", 0xAB, 0x10, 0x1F, "ex_time_core_ring", VPD_KEYWORD_PDG, 0}, //Chiplet specfc - {"ex_time_eco", 0xAC, 0x10, 0x1F, "ex_time_eco_ring", VPD_KEYWORD_PDG, 0}, //Chiplet specfc - {"pb_gptr_dmipll", 0xAD, 0x02, 0x02, "pb_gptr_dmipll_ring", VPD_KEYWORD_PDG, 0}, - {"pb_gptr_mcr", 0xAE, 0x02, 0x02, "pb_gptr_mcr_ring", VPD_KEYWORD_PDG, 0}, - {"pb_gptr_nest", 0xAF, 0x02, 0x02, "pb_gptr_nest_ring", VPD_KEYWORD_PDG, 0}, - {"pb_gptr_nx", 0xB0, 0x02, 0x02, "pb_gptr_nx_ring", VPD_KEYWORD_PDG, 0}, - {"pb_gptr_pcis", 0xB1, 0x02, 0x02, "pb_gptr_pcis_ring", VPD_KEYWORD_PDG, 0}, - {"pb_gptr_perv", 0xB2, 0x02, 0x02, "pb_gptr_perv_ring", VPD_KEYWORD_PDG, 0}, - {"pb_time", 0xB3, 0x02, 0x02, "pb_time_ring", VPD_KEYWORD_PDG, 0}, - {"pb_time_mcr", 0xB4, 0x02, 0x02, "pb_time_mcr_ring", VPD_KEYWORD_PDG, 0}, - {"pb_time_nx", 0xB5, 0x02, 0x02, "pb_time_nx_ring", VPD_KEYWORD_PDG, 0}, - {"pci_gptr_iopci", 0xB6, 0x09, 0x09, "pci_gptr_iopci_ring", VPD_KEYWORD_PDG, 0}, - {"pci_gptr_pbf", 0xB7, 0x09, 0x09, "pci_gptr_pbf_ring", VPD_KEYWORD_PDG, 0}, - {"pci_gptr_pci0", 0xB8, 0x09, 0x09, "pci_gptr_pci0_ring", VPD_KEYWORD_PDG, 0}, - {"pci_gptr_pci1", 0xB9, 0x09, 0x09, "pci_gptr_pci1_ring", VPD_KEYWORD_PDG, 0}, - {"pci_gptr_pci2", 0xBA, 0x09, 0x09, "pci_gptr_pci2_ring", VPD_KEYWORD_PDG, 0}, - {"pci_gptr_perv", 0xBB, 0x09, 0x09, "pci_gptr_perv_ring", VPD_KEYWORD_PDG, 0}, - {"pci_gptr_pll", 0xBC, 0x09, 0x09, "pci_gptr_pll_ring", VPD_KEYWORD_PDG, 0}, - {"pci_time", 0xBD, 0x09, 0x09, "pci_time_ring", VPD_KEYWORD_PDG, 0}, - {"perv_gptr_net", 0xBE, 0x00, 0x00, "perv_gptr_net_ring", VPD_KEYWORD_PDG, 0}, - {"perv_gptr_occ", 0xBF, 0x00, 0x00, "perv_gptr_occ_ring", VPD_KEYWORD_PDG, 0}, - {"perv_gptr_perv", 0xC0, 0x00, 0x00, "perv_gptr_perv_ring", VPD_KEYWORD_PDG, 0}, - {"perv_gptr_pib", 0xC1, 0x00, 0x00, "perv_gptr_pib_ring", VPD_KEYWORD_PDG, 0}, - {"perv_gptr_pll", 0xC2, 0x00, 0x00, "perv_gptr_pll_ring", VPD_KEYWORD_PDG, 0}, - {"perv_time", 0xC3, 0x00, 0x00, "perv_time_ring", VPD_KEYWORD_PDG, 0}, - {"xb_gptr_iopci", 0xC4, 0x04, 0x04, "xb_gptr_iopci_ring", VPD_KEYWORD_PDG, 0}, - {"xb_gptr_iox", 0xC5, 0x04, 0x04, "xb_gptr_iox_ring", VPD_KEYWORD_PDG, 0}, - {"xb_gptr_pben", 0xC6, 0x04, 0x04, "xb_gptr_pben_ring", VPD_KEYWORD_PDG, 0}, - {"xb_gptr_perv", 0xC7, 0x04, 0x04, "xb_gptr_perv_ring", VPD_KEYWORD_PDG, 0}, - {"xb_time", 0xC8, 0x04, 0x04, "xb_time_ring", VPD_KEYWORD_PDG, 0}, - {"pb_gptr_mcl", 0xC9, 0x02, 0x02, "pb_gptr_mcl_ring", VPD_KEYWORD_PDG, 0}, - {"pb_time_mcl", 0xCA, 0x02, 0x02, "pb_time_mcl_ring", VPD_KEYWORD_PDG, 0}, -}; - -const RingIdList RING_ID_LIST_PR[] = { - /* ringName ringId chipIdMin chipIdMax ringNameImg mvpdKeyword */ - {"ab_repr", 0xE0, 0x08, 0x08, "ab_repr_ring", VPD_KEYWORD_PDR, 0}, - {"ex_repr_core", 0xE1, 0x10, 0x1F, "ex_repr_core_ring", VPD_KEYWORD_PDR, 1}, - {"ex_repr_eco", 0xE2, 0x10, 0x1F, "ex_repr_eco_ring", VPD_KEYWORD_PDR, 1}, - {"pb_repr", 0xE3, 0x02, 0x02, "pb_repr_ring", VPD_KEYWORD_PDR, 0}, - {"pb_repr_mcr", 0xE4, 0x02, 0x02, "pb_repr_mcr_ring", VPD_KEYWORD_PDR, 0}, - {"pb_repr_nx", 0xE5, 0x02, 0x02, "pb_repr_nx_ring", VPD_KEYWORD_PDR, 0}, - {"pci_repr", 0xE6, 0x09, 0x09, "pci_repr_ring", VPD_KEYWORD_PDR, 0}, - {"perv_repr", 0xE7, 0x00, 0x00, "perv_repr_ring", VPD_KEYWORD_PDR, 0}, - {"perv_repr_net", 0xE8, 0x00, 0x00, "perv_repr_net_ring", VPD_KEYWORD_PDR, 0}, - {"perv_repr_pib", 0xE9, 0x00, 0x00, "perv_repr_pib_ring", VPD_KEYWORD_PDR, 0}, - {"xb_repr", 0xEA, 0x04, 0x04, "xb_repr_ring", VPD_KEYWORD_PDR, 0}, - {"pb_repr_mcl", 0xEB, 0x02, 0x02, "pb_repr_mcl_ring", VPD_KEYWORD_PDR, 0}, -}; - -const uint32_t RING_ID_LIST_PG_SIZE = sizeof(RING_ID_LIST_PG)/sizeof(RING_ID_LIST_PG[0]); -const uint32_t RING_ID_LIST_PR_SIZE = sizeof(RING_ID_LIST_PR)/sizeof(RING_ID_LIST_PR[0]); - -// get_vpd_ring_list_entry() retrieves the MVPD list entry based on either a ringName -// or a ringId. If both are supplied, only the ringName is used. If ringName==NULL, -// then the ringId is used. A pointer to the RingIdList is returned. -int get_vpd_ring_list_entry(const char *i_ringName, - const uint8_t i_ringId, - RingIdList **i_ringIdList) -{ - int rc=0, NOT_FOUND=1, FOUND=0; - uint8_t iVpdType; - uint8_t iRing; - RingIdList *ring_id_list=NULL; - uint8_t ring_id_list_size; - - rc = NOT_FOUND; - for (iVpdType=0; iVpdType<NUM_OF_VPD_TYPES; iVpdType++) { - if (iVpdType==0) { - ring_id_list = (RingIdList*)RING_ID_LIST_PG; - ring_id_list_size = (uint32_t)RING_ID_LIST_PG_SIZE; - } - else { - ring_id_list = (RingIdList*)RING_ID_LIST_PR; - ring_id_list_size = (uint32_t)RING_ID_LIST_PR_SIZE; - } - // Search the MVPD reference lists for either a: - // - ringName match with or w/o _image in the name, or - // - ringId match. - if (i_ringName) { - // Search for ringName match. - for (iRing=0; iRing<ring_id_list_size; iRing++) { - if ( strcmp((ring_id_list+iRing)->ringName, i_ringName)==0 || - strcmp((ring_id_list+iRing)->ringNameImg,i_ringName)==0 ) { - *i_ringIdList = ring_id_list+iRing; - return FOUND; - } - } - } - else { - // Search for ringId match (since ringName was not supplied). - for (iRing=0; iRing<ring_id_list_size; iRing++) { - if ((ring_id_list+iRing)->ringId==i_ringId) { - *i_ringIdList = ring_id_list+iRing; - return FOUND; - } - } - } - - } - return rc; -} - - - - diff --git a/tools/image/p9_scan_compression.H b/tools/image/p9_scan_compression.H deleted file mode 100644 index 2f1e285d..00000000 --- a/tools/image/p9_scan_compression.H +++ /dev/null @@ -1,345 +0,0 @@ -#ifndef __P9_SCAN_COMPRESSION_H__ -#define __P9_SCAN_COMPRESSION_H__ - -/// This header declares and documents the entry points defined in -/// p9_scan_compression.C. Some constants are also required by the scan -/// decompression HOMER assembly procedures. - -#include "fapi_sbe_common.H" - -#ifndef __ASSEMBLER__ - -#include <stdint.h> - -/// Compressed Scan Chain Data Structure Format -/// -/// The compressed scan ring data structure must be 8-byte aligned in -/// memory. The container data structure consists of this 24-byte header -/// followed by an arbitrary number of 8 byte doublewords containing the -/// compressed scan data. Images are always stored and processed in -/// big-endian byte order. This container format is common across all -/// decompression algorithms. -/// -/// Bytes - Content -/// -/// 0:3 - A 32-bit "magic number" that identifies and validates the -/// compression algorithm and algorithm version used to compress the data. -/// -/// 4:7 - The 32-bit size of the entire data structure in \e bytes. This -/// consists of this 24-byte header plus the compressed scan data. This value -/// is always a multiple of 8. -/// -/// 8:11 - This 32-bit value is reserved to the compression -/// algorithm. Typically this field is used to record the 'size' of the -/// compressed string in units specific to each algorithm. -/// -/// 12:15 - The length of the original scan chain in \e bits. -/// -/// 16:19 - The 32 high-order bits of the value written to the Scan Select -/// register to set up the scan. The Scan Select register only defines these -/// bits. -/// -/// 20 - The Scan Chain Data Structure version number -/// -/// 21 - Flush-optimize : Is this byte is non-zero, the ring state to be -/// modified is the flush state of the ring. -/// -/// 22 - The ring ID uniquely identifying the repair ring name. -/// -/// 23 - The 7-bit pervasive chiplet Id + Multicast bit of the chiplet to -/// scan. This value is loaded directly into P0. The decompression -/// algorithms provide two entry points - one that uses this value as the -/// chiplet Id, and another that allows the caller to specify the chiplet Id -/// in the call. - -typedef struct { - - /// Magic number - See \ref scan_compression_magic - uint32_t iv_magic; - - /// Total size in bytes, including the container header - uint32_t iv_size; - - /// Reserved to the algorithm - uint32_t iv_algorithmReserved; - - /// Length of the original scan chain in bits - uint32_t iv_length; - - /// The high-order 32 bits of the Scan Select Register - /// - /// Note that the Scan Select register only defines the high order 32 - /// bits, so we only need store the 32 high-order bits. This field is - /// 8-byte aligned so that the doubleword loaded by the HOMER can be - /// directly written to the scan select register. - uint32_t iv_scanSelect; - - /// Data structure (header) version - uint8_t iv_headerVersion; - - /// Flush-state optimization - /// - /// Normally, modifying the state of the ring requires XOR-ing the - /// difference state (the compressed state) with the current ring state as - /// it will appear in the Scan Data Register. If the current state of the - /// ring is the scan-0 flush state, then by definition the Scan Data - /// Register is always 0. Therefore we can simply write the difference to - /// the Scan Data Register rather than using a read-XOR-write. - uint8_t iv_flushOptimization; - - /// Ring ID uniquely identifying the repair name. (See the list of ring - /// name vs ring IDs in p8_ring_identification.c). - uint8_t iv_ringId; - - /// 7-bit pervasive chiplet Id + Multicast bit - /// - /// This field is right-justified in an 8-byte aligned doubleword so that - /// the P0 register can be directly updated from the doubelword value in a - /// data register. - uint8_t iv_chipletId; - -} CompressedScanData; - - -/// Endian-translate a CompressedScanData structure -/// -/// \param o_data A pointer to a CompressedScanData structure to receive the -/// endian-translated form of \a i_data. -/// -/// \param i_data A pointer to the original CompressedScanData structure. -/// -/// This API performs an endian-converting copy of a CompressedScanData -/// structure. This copy is guaranteed to be done in such a way that \a i_data -/// and \a o_data may be the same pointer for in-place conversion. Due to the -/// symmetry of reverse, translating a structure twice is always guaranteed to -/// return the origial structure to its original byte order. -void -compressed_scan_data_translate(CompressedScanData* o_data, - CompressedScanData* i_data); - - -/// Compress a scan string using the RS4 compression algorithm -/// -/// \param[in,out] io_data This is a pointer to a memory area which must be -/// large enough to hold the worst-case result of compressing \a i_string (see -/// below). Note that the CompressedScanData is always created in big-endian -/// format, however the caller can use compresed_scan_data_translate() to -/// create a copy of the header in host format. -/// -/// \param[in] i_dataSize The size of \a io_data in bytes. -/// -/// \param[out] o_imageSize The effective size of the entire compressed scan -/// data structure (header + compressed data) created in \a io_data, in bytes. -/// This value will always be a multiple of 8. -/// -/// \param[in] i_string The string to compress. Scan data to compress is -/// left-justified in this input string. -/// -/// \param[in] i_length The length of the input string in \e bits. It is -/// assumed the \a i_string contains at least (\a i_length + 7) / 8 bytes. -/// -/// \param[in] i_scanSelect The 64-bit value written to the Scan Select -/// register to set up for the scan. Only the 32 high-order bits are actually -/// stored. -/// -/// \param[in] i_ringId The ring ID that uniquely identifies the ring name of -/// a repair ring. (See p8_ring_identification.c for more info.) -/// -/// \param[in] i_chipletId The 7-bit value for the iv_chipletId field of the -/// CompressedScanData. -/// -/// \param[in] i_flushOptimization This input parameter should be set to a -/// non-0 value if it is known that this ring difference will be applied to a -/// scan-0 flush state. This will improve the performance of the -/// decompress-scan routine. If the initial state of the ring is unknown, set -/// this parameter to 0. -/// -/// This API is required for integration with PHYP which does not support -/// malloc(). Applications in environments supporting malloc() can use -/// rs4_compress() instead. -/// -/// The worst-case compression for RS4 requires 2 nibbles of control overhead -/// per 15 nibbles of data (17/15), plus a maximum of 2 nibbles of termination. -/// We always require this worst-case amount of memory including the header and -/// any rounding required to guarantee that the data size is a multiple of 8 -/// bytes. The final image size is also rounded up to a multiple of 8 bytes. -/// If the \a i_dataSize is less than this amount (based on \a i_length) the -/// call will fail. -/// -/// \returns See \ref scan_compression_codes -int -_rs4_compress(CompressedScanData* io_data, - uint32_t i_dataSize, - uint32_t* o_imageSize, - const uint8_t* i_string, - const uint32_t i_length, - const uint64_t i_scanSelect, - const uint8_t i_ringId, - const uint8_t i_chipletId, - const uint8_t i_flushOptimization); - - -/// Compress a scan string using the RS4 compression algorithm -/// -/// \param[out] o_data This algorithm uses malloc() to allocate memory for the -/// compresed data, and returns a pointer to this memory in \a o_data. After -/// the call this memory is owned by the caller who is responsible for -/// free()-ing the data area once it is no longer required. Note that the -/// CompressedScanData is always created in big-endian format, however the -/// caller can use compresed_scan_data_translate() to create a copy of the -/// header in host format. -/// -/// \param[out] o_size The effective size of the entire compressed scan data -/// structure (header + compressed data) pointed to by \a o_data, in bytes. -/// This value will always be a multiple of 8. -/// -/// \param[in] i_string The string to compress. Scan data to compress is -/// left-justified in this input string. -/// -/// \param[in] i_length The length of the input string in \e bits. It is -/// assumed the \a i_string contains at least (\a i_length + 7) / 8 bytes. -/// -/// \param[in] i_scanSelect The 64-bit value written to the Scan Select -/// register to set up for the scan. Only the 32 high-order bits are actually -/// stored. -/// -/// \param[in] i_ringId The ring ID that uniquely identifies the ring name of -/// a repair ring. (See p8_ring_identification.c for more info.) -/// -/// \param[in] i_chipletId The 7-bit value for the iv_chipletId field of the -/// CompressedScanData. -/// -/// \param[in] i_flushOptimization This input parameter should be set to a -/// non-0 value if it is known that this ring difference will be applied to a -/// scan-0 flush state. This will improve the performance of the -/// decompress-scan routine. If the initial state of the ring is unknown, set -/// this parameter to 0. -/// -/// \returns See \ref scan_compression_codes -int -rs4_compress(CompressedScanData** o_data, - uint32_t* o_size, - const uint8_t* i_string, - const uint32_t i_length, - const uint64_t i_scanSelect, - const uint8_t i_ringId, - const uint8_t i_chipletId, - const uint8_t i_flushOptimization); - - -/// Decompress a scan string compressed using the RS4 compression algorithm -/// -/// \param[in,out] io_string A caller-supplied data area to contain the -/// decompressed string. The \a i_stringSize must be large enough to contain -/// the decompressed string, which is the size of the original string in bits -/// rounded up to the nearest byte. -/// -/// \param[in] i_stringSize The size (in bytes) of \a i_string. -/// -/// \param[out] o_length The length of the decompressed string in \e bits. -/// -/// \param[in] i_data A pointer to the CompressedScanData header + data to be -/// decompressed. -/// -/// This API is required for integration with PHYP which does not support -/// malloc(). Applications in environments supporting malloc() can use -/// rs4_decompress() instead. -/// -/// \returns See \ref scan_compression_codes -int -_rs4_decompress(uint8_t* i_string, - uint32_t i_stringSize, - uint32_t* o_length, - const CompressedScanData* i_data); - - -/// Decompress a scan string compressed using the RS4 compression algorithm -/// -/// \param[out] o_string The API malloc()-s this data area to contain the -/// decompressed string. After this call the caller owns \a o_string and is -/// responsible for free()-ing this data area once it is no longer required. -/// -/// \param[out] o_length The length of the decompressed string in \e bits. -/// The caller may assume that \a o_string contains at least (\a o_length + 7) -/// / 8 \e bytes. -/// -/// \param[in] i_data A pointer to the CompressedScanData header + data to be -/// decompressed. -/// -/// \returns See \ref scan_compression_codes -int -rs4_decompress(uint8_t** o_string, - uint32_t* o_length, - const CompressedScanData* i_data); - - -/// Determine if an RS4 compressed scan string is all 0 -/// -/// \param[in] i_data A pointer to the CompressedScanData header + data to be -/// -/// \param[out] o_redundant Set to 1 if the RS4 string is the compressed form -/// of a scan string that is all 0; Otherwise set to 0. -/// -/// \returns See \ref scan _compression_code -int -rs4_redundant(const CompressedScanData* i_data, int* o_redundant); - - -#endif // __ASSEMBLER__ - - -/// The current version of the CompressedScanData structure -/// -/// This constant is required to be a #define to guarantee consistency between -/// the header format and cmopiled code. -#define COMPRESSED_SCAN_DATA_VERSION 1 - -/// The size of the CompressedScanData structure -CONST_UINT8_T(COMPRESSED_SCAN_DATA_SIZE, 24); - - -/// \defgroup scan_compression_magic Scan Compression Magic Numbers -/// -/// @ { - -/// RS4 Magic -CONST_UINT32_T(RS4_MAGIC, 0x52533401); /* "RS4" + Version 0x01 */ - -/// @} - - -/// \defgroup scan_compression_codes Scan Compression Return Codes -/// -/// @{ - -/// Normal return code -CONST_UINT8_T(SCAN_COMPRESSION_OK, 0); - -/// The (de)compression algorithm could not allocate enough memory for the -/// (de)compression. -CONST_UINT8_T(SCAN_COMPRESSION_NO_MEMORY, 1); - -/// Magic number mismatch on scan decompression -CONST_UINT8_T(SCAN_DECOMPRESSION_MAGIC_ERROR, 2); - -/// Decompression size error -/// -/// Decompression produced a string of a size different than indicated in the -/// header, indicating either a bug or data corruption. Note that the entire -/// application should be considered corrupted if this error occurs since it -/// may not be discovered until after the decompression buffer is -/// overrun. This error may also be returned by rs4_redundant() in the event -/// of inconsistencies in the compressed string. -CONST_UINT8_T(SCAN_DECOMPRESSION_SIZE_ERROR, 3); - -/// A buffer would overflow -/// -/// Either the caller-supplied memory buffer to _rs4_decompress() was too -/// small to contain the decompressed string, or a caller-supplied buffer to -/// _rs4_compress() was not large enough to hold the worst-case compressed -/// string. -CONST_UINT8_T(SCAN_COMPRESSION_BUFFER_OVERFLOW, 4); - -/// @} - -#endif // __P8_SCAN_COMPRESSION_H__ diff --git a/tools/image/sbe_default_tool.c b/tools/image/sbe_default_tool.c index 3bd90438..8ea0e58d 100644 --- a/tools/image/sbe_default_tool.c +++ b/tools/image/sbe_default_tool.c @@ -1,5 +1,5 @@ /// \file sbe_default_tool.c -/// \brief SBE-XIP image setter tool for attributes in fixed section +/// \brief P9-XIP image setter tool for attributes in fixed section /// #include <sys/mman.h> #include <sys/stat.h> @@ -18,7 +18,7 @@ #define __PPE__ #include "fapi2.H" #include "proc_sbe_fixed.H" -#include "sbe_xip_image.h" +#include "p9_xip_image.h" const char* g_usage = "Usage: sbe_default_tool <image> <attribute> <value> <target type> <index>\n" @@ -88,11 +88,11 @@ void assertTarget(const char* str, unsigned int index) void setAttribute(void* image, const char* attribute, unsigned int index, uint64_t val) { - SbeXipItem item; + P9XipItem item; void *thePointer; int rc; - rc = sbe_xip_find(image, attribute, &item); + rc = p9_xip_find(image, attribute, &item); if (rc) { fprintf(stderr, "sbe_default_tool: attribute not existing:"); fprintf(stderr, " %s", attribute); @@ -103,40 +103,40 @@ void setAttribute(void* image, const char* attribute, unsigned int index, uint64 //printf("offset in string section: 0x%x \n", be32toh(item.iv_toc->iv_id)); //printf("address: 0x%x index: %2d 0x%x\n", item.iv_address, index, index); - sbe_xip_image2host(image, item.iv_address, &thePointer); + p9_xip_image2host(image, item.iv_address, &thePointer); // debug purpose //printf("pointer1: 0x%x val: 0x%llx \n", thePointer, val); - if(item.iv_toc->iv_type == SBE_XIP_UINT8) { + if(item.iv_toc->iv_type == P9_XIP_UINT8) { *((uint8_t*)thePointer + (index * sizeof(uint8_t))) = (uint8_t)val; - } else if(item.iv_toc->iv_type == SBE_XIP_INT8) { + } else if(item.iv_toc->iv_type == P9_XIP_INT8) { *((int8_t*)thePointer + (index * sizeof(int8_t))) = (int8_t)val; - } else if(item.iv_toc->iv_type == SBE_XIP_UINT16) { + } else if(item.iv_toc->iv_type == P9_XIP_UINT16) { *((uint16_t*)thePointer + (index * sizeof(uint16_t))) = xipRevLe16((uint16_t)val); - } else if(item.iv_toc->iv_type == SBE_XIP_INT16) { + } else if(item.iv_toc->iv_type == P9_XIP_INT16) { *((int16_t*)thePointer + (index * sizeof(int16_t))) = xipRevLe16((int16_t)val); - } else if(item.iv_toc->iv_type == SBE_XIP_UINT32) { + } else if(item.iv_toc->iv_type == P9_XIP_UINT32) { *((uint32_t*)thePointer + (index * sizeof(uint32_t))) = xipRevLe32((uint32_t)val); - } else if(item.iv_toc->iv_type == SBE_XIP_INT32) { + } else if(item.iv_toc->iv_type == P9_XIP_INT32) { *((int32_t*)thePointer + (index * sizeof(int32_t))) = xipRevLe32((int32_t)val); - } else if(item.iv_toc->iv_type == SBE_XIP_UINT64) { + } else if(item.iv_toc->iv_type == P9_XIP_UINT64) { *((uint64_t*)thePointer + (index * sizeof(uint64_t))) = xipRevLe64((uint64_t)val); - } else if(item.iv_toc->iv_type == SBE_XIP_INT64) { + } else if(item.iv_toc->iv_type == P9_XIP_INT64) { *((int64_t*)thePointer + (index * sizeof(int64_t))) = xipRevLe64((int64_t)val); @@ -148,8 +148,8 @@ void setAttribute(void* image, const char* attribute, unsigned int index, uint64 - SBE_XIP_SECTION_NAMES(section_name); - SBE_XIP_TYPE_STRINGS(type_name); + P9_XIP_SECTION_NAMES(section_name); + P9_XIP_TYPE_STRINGS(type_name); // debug purpose //printf("pointer2: 0x%x \n", thePointer + index); @@ -166,51 +166,51 @@ uint64_t getAttribute(void* image, const char* attribute, unsigned int index) { uint64_t val = 0; - SbeXipItem item; + P9XipItem item; void *thePointer; int rc; - rc = sbe_xip_find(image, attribute, &item); + rc = p9_xip_find(image, attribute, &item); if (rc) { fprintf(stderr, "sbe_default_tool: attribute not existing:"); fprintf(stderr, " %s", attribute); exit(1); } - sbe_xip_image2host(image, item.iv_address, &thePointer); + p9_xip_image2host(image, item.iv_address, &thePointer); - if(item.iv_toc->iv_type == SBE_XIP_UINT8) { + if(item.iv_toc->iv_type == P9_XIP_UINT8) { val = *((uint8_t*)thePointer + (index * sizeof(uint8_t))); - } else if(item.iv_toc->iv_type == SBE_XIP_INT8) { + } else if(item.iv_toc->iv_type == P9_XIP_INT8) { val = *((int8_t*)thePointer + (index * sizeof(int8_t))); val &= 0xFF; - } else if(item.iv_toc->iv_type == SBE_XIP_UINT16) { + } else if(item.iv_toc->iv_type == P9_XIP_UINT16) { val = xipRevLe16(*((uint16_t*)thePointer + (index * sizeof(uint16_t)))); - } else if(item.iv_toc->iv_type == SBE_XIP_INT16) { + } else if(item.iv_toc->iv_type == P9_XIP_INT16) { val = xipRevLe16(*((int16_t*)thePointer + (index * sizeof(int16_t)))); val &= 0xFFFF; - } else if(item.iv_toc->iv_type == SBE_XIP_UINT32) { + } else if(item.iv_toc->iv_type == P9_XIP_UINT32) { val = xipRevLe32(*((uint32_t*)thePointer + (index * sizeof(uint32_t)))); - } else if(item.iv_toc->iv_type == SBE_XIP_INT32) { + } else if(item.iv_toc->iv_type == P9_XIP_INT32) { val = xipRevLe32(*((int32_t*)thePointer + (index * sizeof(int32_t)))); val &= 0xFFFFFFFF; - } else if(item.iv_toc->iv_type == SBE_XIP_UINT64) { + } else if(item.iv_toc->iv_type == P9_XIP_UINT64) { val = xipRevLe64(*((uint64_t*)thePointer + (index * sizeof(uint64_t)))); - } else if(item.iv_toc->iv_type == SBE_XIP_INT64) { + } else if(item.iv_toc->iv_type == P9_XIP_INT64) { val = xipRevLe64(*((int64_t*)thePointer + (index * sizeof(int64_t)))); diff --git a/tools/image/sbe_xip_tool.c b/tools/image/sbe_xip_tool.c deleted file mode 100644 index 8c98c402..00000000 --- a/tools/image/sbe_xip_tool.c +++ /dev/null @@ -1,2107 +0,0 @@ -// $Id: sbe_xip_tool.c,v 1.13 2014/06/27 20:50:16 maploetz Exp $ - -/// \file sbe_xip_tool.c -/// \brief SBE-XIP image search/edit tool -/// -/// Note: This file was originally stored under .../procedures/ipl/sbe. It -/// was moved here at version 1.19. - -#include <sys/mman.h> -#include <sys/stat.h> -#include <sys/types.h> - -#include <errno.h> -#include <fcntl.h> -#include <regex.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - - - -#define __PPE__ -#include "fapi2.H" -#include "proc_sbe_fixed.H" -#include "sbe_xip_image.h" - -#include "sbe_link.H" -#include "p9_image_help_base.H" -#include "p9_ring_identification.H" -#include "p9_scan_compression.H" - -// Usage: sbe_xip_tool <image> [-<flag> ...] normalize -// sbe_xip_tool <image> [-<flag> ...] get <item> -// sbe_xip_tool <image> [-<flag> ...] getv <item> <index> -// sbe_xip_tool <image> [-<flag> ...] set <item> <value> [ <item1> <value1> ... ] -// sbe_xip_tool <image> [-<flag> ...] setv <item> <index> <value> [ <item1> <index1> <value1> ... ] -// sbe_xip_tool <image> [-<flag> ...] report [<regex>] -// sbe_xip_tool <image> [-<flag> ...] append <section> <file> -// sbe_xip_tool <image> [-<flag> ...] extract <section> <file> -// sbe_xip_tool <image> [-<flag> ...] delete [ <section0> ... <sectionN> ] -// sbe_xip_tool <image> [-<flag> ...] dis <section or .rings_summary>\n"// -// -// This simple application uses the SBE-XIP image APIs to normalize, search -// update and edit SBE-XIP images. This program encapsulates several commands -// in a common command framework which requires an image to operate on, a -// command name, and command arguments that vary by command. Commands that -// modify the image always rewrite the image in-place in the filesystem; -// however the original image is only modified if the command has completed -// without error. -// -// The program operates on an SBE-XIP format binary image, which must be -// normalized - unless the tool is being called to normalize the image in the -// first place using the 'normalize' command. The tool also validates the -// image prior to operating on the image. -// -// The 'get' command retrieves a scalar value from the image and prints its -// representation on stdout (followed by a newline). Scalar integer values -// and image addresses are printed as hex numbers (0x...). Strings are printed -// verbatim. -// -// The 'getv' command retrieves a vector element from the image and prints its -// representation on stdout (followed by a newline). Integer values -// and image addresses are printed as hex numbers (0x...). Vectors of strings -// are not supported. -// -// The 'set' command allows setting integer and string values in the image. -// New integer values can be specified in decimal or hex (0x...). Strings are -// taken verbatim from the command line. Note that new string values will be -// silently truncated to the length of the current string if the new value is -// longer than the current string. Updating address values is currently not -// supported. Any number of item/value pairs can be specified with a single -// 'set' command. -// -// The 'setv' command is provided to set individual vector elements of -// integral arrays. -// -// The 'report' command prints a report including a dump of the header and -// section table, a listing of the types and values of all items that appear -// in the TOC. The TOC listing includes the -// sequence number of the entry in the TOC, the item name, the item type and -// the item value. -// -// The 'append' command either creates or extends the section named by the -// section argument, by appending the contents of the named file verbatim. -// Currently the section must either be the final (highest address) section of -// the image, or must be empty, in which case the append command creates the -// section as the final section of the image. The 'append' command writes the -// relocatable image address where the input file was loaded to stdout. -// -// The 'extract' command extracts a sections from the binary image. -// -// The 'delete' command deletes 0 or more sections, starting with <section0>. -// Each section to be deleted must either be the final (highest address) -// section of the image at the time it is deleted, or must be empty. The -// 'delete' command writes the size of the final modified image to stdout. -// -// The 'dis' command disassembles the section named by the section argument. -// Note that the section name .rings_summary, which is not an actual XIP -// section name, merely indicates to summarize the .rings section. -// -// The following -i<flag> are supported: -// -ifs -// causes the validation step to ignore image size check against the file -// size. -// -iv -// causes all validation checking to be ignored. (Skips validation step.) - -const char* g_usage = -"Usage: sbe_xip_tool <image> [-i<flag> ...] normalize\n" -" sbe_xip_tool <image> [-i<flag> ...] get <item>\n" -" sbe_xip_tool <image> [-i<flag> ...] getv <item> <index>\n" -" sbe_xip_tool <image> [-i<flag> ...] set <item> <value> [ <item1> <value1> ... ]\n" -" sbe_xip_tool <image> [-i<flag> ...] setv <item> <index> <value> [ <item1> <index1> <value1> ... ]\n" -" sbe_xip_tool <image> [-i<flag> ...] report [<regex>]\n" -" sbe_xip_tool <image> [-i<flag> ...] append <section> <file>\n" -" sbe_xip_tool <image> [-i<flag> ...] extract <section> <file>\n" -" sbe_xip_tool <image> [-i<flag> ...] delete [ <section0> ... <sectionN> ]\n" -" sbe_xip_tool <image> [-i<flag> ...] dis <section or .rings_summary>\n"//\n" -"\n" -"This simple application uses the SBE-XIP image APIs to normalize, search\n" -"update and edit SBE-XIP images. This program encapsulates several commands\n" -"in a common command framework which requires an image to operate on, a\n" -"command name, and command arguments that vary by command. Commands that\n" -"modify the image always rewrite the image in-place in the filesystem;\n" -"however the original image is only modified if the command has completed\n" -"without error.\n" -"\n" -"The program operates on an SBE-XIP format binary image, which must be\n" -"normalized - unless the tool is being called to normalize the image in the\n" -"first place using the 'normalize' command. The tool also validates the\n" -"image prior to operating on the image.\n" -"\n" -"The 'get' command retrieves a scalar value from the image and prints its\n" -"representation on stdout (followed by a newline). Scalar integer values\n" -"and image addresses are printed as hex numbers (0x...). Strings are printed\n" -"verbatim.\n" -"\n" -"The 'getv' command retrieves a vector element from the image and prints its\n" -"representation on stdout (followed by a newline). Integer values\n" -"and image addresses are printed as hex numbers (0x...). Vectors of strings\n" -"are not supported.\n" -"\n" -"The 'set' command allows setting integer and string values in the image.\n" -"New integer values can be specified in decimal or hex (0x...). Strings are\n" -"taken verbatim from the command line. Note that new string values will be\n" -"silently truncated to the length of the current string if the new value is\n" -"longer than the current string. Updating address values is currently not\n" -"supported. Any number of item/value pairs can be specified with a single\n" -"'set' command.\n" -"\n" -"The 'setv' command is provided to set individual vector elements of\n" -"integral arrays.\n" -"\n" -"The 'report' command prints a report including a dump of the header and\n" -"section table, a listing of the types and values of all items that appear\n" -"in the TOC. The TOC listing includes the\n" -"sequence number of the entry in the TOC, the item name, the item type and\n" -"the item value.\n" -"\n" -"The 'append' command either creates or extends the section named by the\n" -"section argument, by appending the contents of the named file verbatim.\n" -"Currently the section must either be the final (highest address) section of\n" -"the image, or must be empty, in which case the append command creates the\n" -"section as the final section of the image. The 'append' command writes the\n" -"relocatable image address where the input file was loaded to stdout.\n" -"\n" -"The 'extract' command extracs a sections from a binary image.\n" -"\n" -"The 'delete' command deletes 0 or more sections, starting with <section0>.\n" -"Each section to be deleted must either be the final (highest address)\n" -"section of the image at the time it is deleted, or must be empty. The\n" -"'delete' command writes the size of the final modified image to stdout.\n" -"\n" -"The 'dis' command disassembles the section named by the section argument.\n" -"Note that the section name .rings_summary, which is not an actual XIP\n" -"section name, merely indicates to summarize the .rings section.\n" -"\n" -"-i<flag>:\n" -"\t-ifs Causes the validation step to ignore image size check against the\n" -"\tfile size.\n" -"\t-iv Causes all validation checking to be ignored.\n" - ; - -SBE_XIP_ERROR_STRINGS(g_errorStrings); -SBE_XIP_TYPE_STRINGS(g_typeStrings); -SBE_XIP_TYPE_ABBREVS(g_typeAbbrevs); -SBE_XIP_SECTION_NAMES(g_sectionNames); -// Disassembler error support. -DIS_ERROR_STRINGS(g_errorStringsDis); - -#define ERRBUF_SIZE 60 - -typedef struct { - int index; - int regex; - regex_t preg; -} ReportControl; - -off_t g_imageSize; - - -// Byte-reverse a 32-bit integer if on an LE machine -inline uint32_t -myRev32(const uint32_t i_x) -{ - uint32_t rx; - -#ifdef _BIG_ENDIAN - rx = i_x; -#else - uint8_t *pix = (uint8_t*)(&i_x); - uint8_t *prx = (uint8_t*)(&rx); - - prx[0] = pix[3]; - prx[1] = pix[2]; - prx[2] = pix[1]; - prx[3] = pix[0]; -#endif - - return rx; -} - -// Byte-reverse a 64-bit integer if on a little-endian machine -inline uint64_t -myRev64(const uint64_t i_x) -{ - uint64_t rx; - -#ifdef _BIG_ENDIAN - rx = i_x; -#else - uint8_t *pix = (uint8_t*)(&i_x); - uint8_t *prx = (uint8_t*)(&rx); - - prx[0] = pix[7]; - prx[1] = pix[6]; - prx[2] = pix[5]; - prx[3] = pix[4]; - prx[4] = pix[3]; - prx[5] = pix[2]; - prx[6] = pix[1]; - prx[7] = pix[0]; -#endif - - return rx; -} - -// Normalize an SBE-XIP image. We normalize a copy of the image first so that -// the original image will be available for debugging in case the -// normalization fails, then validate and copy the normalized image back to -// the mmap()-ed file. - -int -normalize(void* io_image, const int i_argc, const char** i_argv, uint32_t i_maskIgnores) -{ - int rc; - void *copy; - - do { - - // The 'normalize' command takes no arguments - - if (i_argc != 0) { - fprintf(stderr, g_usage); - exit(1); - } - - copy = malloc(g_imageSize); - if (copy == 0) { - perror("malloc() failed : "); - exit(1); - } - - memcpy(copy, io_image, g_imageSize); - - rc = sbe_xip_normalize(copy); - if (rc) break; - - if ( !(i_maskIgnores & SBE_XIP_IGNORE_ALL) ) { - rc = sbe_xip_validate2(copy, g_imageSize, i_maskIgnores); - } - if (rc) break; - - memcpy(io_image, copy, g_imageSize); - - } while (0); - - return rc; -} - - -// Print a line of a report, listing the index, symbol, type and current -// value. - -int -tocListing(void* io_image, - const SbeXipItem* i_item, - void* arg) -{ - int rc; - ReportControl *control; - uint64_t data; - char* s; - - control = (ReportControl*)arg; - - do { - rc = 0; - - if (control->regex) { - if (regexec(&(control->preg), i_item->iv_id, 0, 0, 0)) { - break; - } - } - - printf("0x%04x | %-42s | %s | ", - control->index, i_item->iv_id, - SBE_XIP_TYPE_STRING(g_typeAbbrevs, i_item->iv_type)); - - switch (i_item->iv_type) { - case SBE_XIP_UINT8: - rc = sbe_xip_get_scalar(io_image, i_item->iv_id, &data); - if (rc) break; - printf("0x%02x", (uint8_t)data); - break; - case SBE_XIP_UINT16: - rc = sbe_xip_get_scalar(io_image, i_item->iv_id, &data); - if (rc) break; - printf("0x%04x", (uint16_t)data); - break; - case SBE_XIP_UINT32: - rc = sbe_xip_get_scalar(io_image, i_item->iv_id, &data); - if (rc) break; - printf("0x%08x", (uint32_t)data); - break; - case SBE_XIP_UINT64: - rc = sbe_xip_get_scalar(io_image, i_item->iv_id, &data); - if (rc) break; - printf("0x%016llx", data); - break; - case SBE_XIP_INT8: - rc = sbe_xip_get_scalar(io_image, i_item->iv_id, &data); - if (rc) break; - printf("0x%02x", (uint8_t)data); - break; - case SBE_XIP_INT16: - rc = sbe_xip_get_scalar(io_image, i_item->iv_id, &data); - if (rc) break; - printf("0x%04x", (uint16_t)data); - break; - case SBE_XIP_INT32: - rc = sbe_xip_get_scalar(io_image, i_item->iv_id, &data); - if (rc) break; - printf("0x%08x", (uint32_t)data); - break; - case SBE_XIP_INT64: - rc = sbe_xip_get_scalar(io_image, i_item->iv_id, &data); - if (rc) break; - printf("0x%016llx", data); - break; - case SBE_XIP_STRING: - rc = sbe_xip_get_string(io_image, i_item->iv_id, &s); - if (rc) break; - printf("%s", s); - break; - case SBE_XIP_ADDRESS: - rc = sbe_xip_get_scalar(io_image, i_item->iv_id, &data); - if (rc) break; - printf("0x%04x:0x%08x", - (uint16_t)((data >> 32) & 0xffff), - (uint32_t)(data & 0xffffffff)); - break; - default: - printf("unknown type\n"); - rc = SBE_XIP_BUG; - break; - } - printf("\n"); - } while (0); - control->index += 1; - return rc; -} - - -// Dump the image header, including the section table - -int -dumpHeader(void* i_image) -{ - int i; - SbeXipHeader header; - SbeXipSection* section; - char magicString[9]; - - SBE_XIP_SECTION_NAMES(section_name); - - // Dump header information. Since the TOC may not exist we need to get - // the information from the header explicitly. - - sbe_xip_translate_header(&header, (SbeXipHeader*)i_image); - - memcpy(magicString, (char*)(&(((SbeXipHeader*)i_image)->iv_magic)), 8); - magicString[8] = 0; - - printf("Magic Number : 0x%016llx \"%s\"\n", - header.iv_magic, magicString); - printf("Header Version : 0x%02x\n", header.iv_headerVersion); - printf("Link Address : 0x%016llx\n", header.iv_linkAddress); - printf("Entry Offset : 0x%08x\n", (uint32_t)header.iv_entryOffset); - printf("Image Size : 0x%08x (%d)\n", - header.iv_imageSize, header.iv_imageSize); - printf("Normalized : %s\n", header.iv_normalized ? "Yes" : "No"); - printf("TOC Sorted : %s\n", header.iv_tocSorted ? "Yes" : "No"); - printf("Build Date : %02d/%02d/%04d\n", - (header.iv_buildDate / 100) % 100, - header.iv_buildDate % 100, - header.iv_buildDate / 10000); - printf("Build Time : %02d:%02d\n", - header.iv_buildTime / 100, - header.iv_buildTime % 100); - printf("Build User : %s\n", header.iv_buildUser); - printf("Build Host : %s\n", header.iv_buildHost); - printf("\n"); - - printf("Section Table : Offset Size\n"); - printf("\n"); - - for (i = 0; i < SBE_XIP_SECTIONS; i++) { - section = &(header.iv_section[i]); - printf("%-16s 0x%08x 0x%08x (%d)\n", - section_name[i], - section->iv_offset, section->iv_size, section->iv_size); - } - - printf("\n"); - - return 0; -} - - -// Print a report - -int -report(void* io_image, const int i_argc, const char** i_argv) -{ - int rc; - ReportControl control; - char errbuf[ERRBUF_SIZE]; - - do { - - // Basic syntax check : [<regexp>] - - if (i_argc > 1) { - fprintf(stderr, g_usage); - exit(1); - } - - // Compile a regular expression if supplied - - if (i_argc == 1) { - rc = regcomp(&(control.preg), i_argv[0], REG_NOSUB); - if (rc) { - regerror(rc, &(control.preg), errbuf, ERRBUF_SIZE); - fprintf(stderr, "Error from regcomp() : %s\n", errbuf); - exit(1); - } - control.regex = 1; - } else { - control.regex = 0; - - dumpHeader(io_image); - printf("TOC Report\n\n"); - } - - // Map the TOC with the mapReport() function - - control.index = 0; - rc = sbe_xip_map_toc(io_image, tocListing, (void*)(&control)); - if (rc) break; - - } while (0); - - return rc; -} - - -// Set a scalar or vector element values in the image. The 'i_setv' argument -// indicates set/setv (0/1). - -int -set(void* io_image, const int i_argc, const char** i_argv, int i_setv) -{ - int rc, arg, base, clause_args, index_val; - SbeXipItem item; - unsigned long long newValue; - const char *key, *index, *value; - char *endptr; - - do { - - // Basic syntax check: <item> <value> [ <item1> <value1> ... ] - // Basic syntax check: <item> <index> <value> [ <item1> <index1> <value1> ... ] - - clause_args = (i_setv ? 3 : 2); - - if ((i_argc % clause_args) != 0) { - fprintf(stderr, g_usage); - exit(1); - } - - for (arg = 0; arg < i_argc; arg += clause_args) { - - key = i_argv[arg]; - if (i_setv) { - index = i_argv[arg + 1]; - index_val = strtol(index, 0, 0); - value = i_argv[arg + 2]; - } else { - index = ""; - index_val = 0; - value = i_argv[arg + 1]; - } - - // Search for the item to see what type of data it expects, then - // case split on the type. - - rc = sbe_xip_find(io_image, key, &item); - if (rc) break; - - if (index_val < 0) { - fprintf(stderr, - "Illegal negative vector index %s for %s\n", - index, key); - exit(1); - } else if ((item.iv_elements != 0) && - (index_val >= item.iv_elements)) { - fprintf(stderr, - "Index %s out-of-bounds for %s (%d elements)\n", - index, key, item.iv_elements); - exit(1); - } - - switch (item.iv_type) { - case SBE_XIP_UINT8: - case SBE_XIP_UINT16: - case SBE_XIP_UINT32: - case SBE_XIP_UINT64: - - // We need to do a bit of preprocessing on the string to - // determine its format and set the base for strtoull(), - // otherwise strtoull() will be confused by leading zeros - // e.g. in time strings generated by `date +%H%M`, and try to - // process the string as octal. - - if ((strlen(value) >= 2) && (value[0] == '0') && - ((value[1] == 'x') || (value[1] == 'X'))) { - base = 16; - } else { - base = 10; - } - - errno = 0; - newValue = strtoull(value, &endptr, base); - if ((errno != 0) || (endptr != (value + strlen(value)))) { - fprintf(stderr, - "Error parsing putative integer value : %s\n", - value); - exit(1); - } - - switch (item.iv_type) { - - case SBE_XIP_UINT8: - if ((uint8_t)newValue != newValue) { - fprintf(stderr, - "Value 0x%016llx too large for 8-bit type\n", - newValue); - exit(1); - } - break; - - case SBE_XIP_UINT16: - if ((uint16_t)newValue != newValue) { - fprintf(stderr, - "Value 0x%016llx too large for 16-bit type\n", - newValue); - exit(1); - } - break; - - case SBE_XIP_UINT32: - if ((uint32_t)newValue != newValue) { - fprintf(stderr, - "Value 0x%016llx too large for 32-bit type\n", - newValue); - exit(1); - } - break; - - case SBE_XIP_UINT64: - break; - - default: - break; - } - - rc = sbe_xip_set_element(io_image, key, index_val, newValue); - if (rc) rc = SBE_XIP_BUG; - break; - - case SBE_XIP_STRING: - - if (i_setv) { - fprintf(stderr, "Can't use 'setv' for string data %s\n", - key); - exit(1); - } - rc = sbe_xip_set_string(io_image, key, (char*)value); - if (rc) rc = SBE_XIP_BUG; - break; - case SBE_XIP_INT8: - case SBE_XIP_INT16: - case SBE_XIP_INT32: - case SBE_XIP_INT64: - fprintf(stderr, - "Item %s has int type %s, " - "which is not supported for '%s'.\n", - i_argv[arg], - SBE_XIP_TYPE_STRING(g_typeStrings, item.iv_type), - (i_setv ? "setv" : "set")); - exit(1); - break; - default: - fprintf(stderr, - "Item %s has type %s, " - "which is not supported for '%s'.\n", - i_argv[arg], - SBE_XIP_TYPE_STRING(g_typeStrings, item.iv_type), - (i_setv ? "setv" : "set")); - exit(1); - break; - } - - if (rc) break; - - } - } while (0); - - //if good rc, we need to msync the mmaped file to push contents to - //the actual file. Per man page this is required although some - //file systems (notably AFS) don't seem to require (GSA does) - if(!rc) - { - uint8_t i = 0; - do { - rc = msync(io_image, g_imageSize , MS_SYNC); - if(rc) - { - i++; - fprintf(stderr, - "msync failed with errno %d\n", errno); - } - } while(rc && i < 5); - - if(rc) - { - exit(3); - } - } - - return rc; -} - - -// Get a value from the image, and return on stdout. The 'i_getv' argument -// indicates get/getv (0/1) - -int -get(void* i_image, const int i_argc, const char** i_argv, int i_getv) -{ - int rc, nargs, index_val; - SbeXipItem item; - const char *key, *index; - uint64_t data; - char* s; - - do { - - // Basic syntax check: <item> - // Basic syntax check: <item> <index> - - nargs = (i_getv ? 2 : 1); - - if (i_argc != nargs) { - fprintf(stderr, g_usage); - exit(1); - } - - key = i_argv[0]; - if (i_getv) { - index = i_argv[1]; - index_val = strtol(index, 0, 0); - } else { - index = ""; - index_val = 0; - } - - // Search for the item to determine its type, then case split on the - // type. - - rc = sbe_xip_find(i_image, key, &item); - if (rc) break; - - if (index_val < 0) { - fprintf(stderr, - "Illegal negative vector index %s for %s\n", - index, key); - exit(1); - } else if ((item.iv_elements != 0) && - (index_val >= item.iv_elements)) { - fprintf(stderr, "Index %s out-of-bounds for %s (%d elements)\n", - index, key, item.iv_elements); - exit(1); - } - - switch (item.iv_type) { - - case SBE_XIP_UINT8: - case SBE_XIP_UINT16: - case SBE_XIP_UINT32: - case SBE_XIP_UINT64: - rc = sbe_xip_get_element(i_image, key, index_val, &data); - if (rc) { - rc = SBE_XIP_BUG; - break; - } - switch (item.iv_type) { - case SBE_XIP_UINT8: - printf("0x%02x\n", (uint8_t)data); - break; - case SBE_XIP_UINT16: - printf("0x%04x\n", (uint16_t)data); - break; - case SBE_XIP_UINT32: - printf("0x%08x\n", (uint32_t)data); - break; - case SBE_XIP_UINT64: - printf("0x%016llx\n", data); - break; - default: - break; - } - break; - - case SBE_XIP_ADDRESS: - if (i_getv) { - fprintf(stderr, "Can't use 'getv' for address data : %s\n", - key); - exit(1); - } - rc = sbe_xip_get_scalar(i_image, key, &data); - if (rc) { - rc = SBE_XIP_BUG; - break; - } - printf("0x%012llx\n", data); - break; - - case SBE_XIP_STRING: - if (i_getv) { - fprintf(stderr, "Can't use 'getv' for string data : %s\n", - key); - exit(1); - } - rc = sbe_xip_get_string(i_image, key, &s); - if (rc) { - rc = SBE_XIP_BUG; - break; - } - printf("%s\n", s); - break; - default: - fprintf(stderr, "%s%d : Bug, unexpected type %d\n", - __FILE__, __LINE__, item.iv_type); - exit(1); - break; - } - } while (0); - - return rc; -} - - -// strtoul() with application-specific error handling - -unsigned long -localStrtoul(const char* s) -{ - unsigned long v; - char* endptr; - - errno = 0; - v = strtoul(s, &endptr, 0); - if ((errno != 0) || (endptr != (s + strlen(s)))) { - fprintf(stderr, - "Error parsing putative integer value : %s\n", - s); - exit(1); - } - return v; -} - - -// Append a file to section -int -append(const char* i_imageFile, const int i_imageFd, void* io_image, - int i_argc, const char** i_argv) -{ - int fileFd, newImageFd, sectionId, rc; - struct stat buf; - const char* section; - const char* file; - void* appendImage; - void* newImage; - uint32_t size, newSize, sectionOffset; - uint64_t homerAddress; - - do { - - // Basic syntax check: <section> <file> - - if (i_argc != 2) { - fprintf(stderr, g_usage); - exit(1); - } - section = i_argv[0]; - file = i_argv[1]; - - // Translate the section name to a section Id - - for (sectionId = 0; sectionId < SBE_XIP_SECTIONS; sectionId++) { - if (strcmp(section, g_sectionNames[sectionId]) == 0) { - break; - } - } - if (sectionId == SBE_XIP_SECTIONS) { - fprintf(stderr, "Unrecognized section name : '%s;\n", - section); - exit(1); - } - - - // Open and mmap the file to be appended - - fileFd = open(file, O_RDONLY); - if (fileFd < 0) { - perror("open() of the file to be appended failed : "); - exit(1); - } - - rc = fstat(fileFd, &buf); - if (rc) { - perror("fstat() of the file to be appended failed : "); - exit(1); - } - - appendImage = mmap(0, buf.st_size, PROT_READ, MAP_SHARED, fileFd, 0); - if (appendImage == MAP_FAILED) { - perror("mmap() of the file to be appended failed : "); - exit(1); - } - - - // malloc() a buffer for the new image, adding space for alignment - - rc = sbe_xip_image_size(io_image, &size); - if (rc) break; - - newSize = size + buf.st_size + SBE_XIP_MAX_SECTION_ALIGNMENT; - - newImage = malloc(newSize); - - if (newImage == 0) { - fprintf(stderr, "Can't malloc() a buffer for the new image\n"); - exit(1); - } - - - // Copy the image. At this point the original image file must be - // closed. - - memcpy(newImage, io_image, size); - - rc = close(i_imageFd); - if (rc) { - perror("close() of the original image file failed : "); - exit(1); - } - - - // Do the append and print the image address where the data was loaded. - // We will not fail for unaligned addresses, as we have no knowledge - // of whether or why the user wants the final image address. - - rc = sbe_xip_append(newImage, sectionId, - appendImage, buf.st_size, - newSize, §ionOffset); - if (rc) break; - - rc = sbe_xip_section2image(newImage, sectionId, sectionOffset, - &homerAddress); - if (rc && (rc != SBE_XIP_ALIGNMENT_ERROR)) break; - - printf("0x%016llx\n", homerAddress); - - - // Now write the new image back to the filesystem - - newImageFd = open(i_imageFile, O_WRONLY | O_TRUNC); - if (newImageFd < 0) { - perror("re-open() of image file failed : "); - exit(1); - } - - rc = sbe_xip_image_size(newImage, &size); - if (rc) break; - - rc = write(newImageFd, newImage, size); - if ((rc < 0) || ((uint32_t)rc != size)) { - perror("write() of modified image failed : "); - exit(1); - } - - rc = close(newImageFd); - if (rc) { - perror("close() of modified image failed : "); - exit(1); - } - } while (0); - - return rc; -} - -// Extract section from a file -int -extract(const char* i_imageFile, const int i_imageFd, void* io_image, - int i_argc, const char** i_argv) -{ - int fileFd, newImageFd, sectionId, rc; - void* newImage; - const char* section; - const char* file; - struct stat buf; - SbeXipHeader header; - SbeXipSection* xSection; - uint32_t size; - uint32_t offset; - unsigned int i; - - do { - - if (i_argc != 2) { - fprintf(stderr, g_usage); - exit(1); - } - section = i_argv[0]; - file = i_argv[1]; - - printf("%s %s\n", section , file); - - for (sectionId = 0; sectionId < SBE_XIP_SECTIONS; sectionId++) { - if (strcmp(section, g_sectionNames[sectionId]) == 0) { - break; - } - } - if (sectionId == SBE_XIP_SECTIONS) { - fprintf(stderr, "Unrecognized section name : '%s;\n", - section); - exit(1); - } - - sbe_xip_translate_header(&header, (SbeXipHeader*)io_image); - - for (i = 0; i < SBE_XIP_SECTIONS; i++) { - xSection = &(header.iv_section[i]); - - if (strcmp(section, g_sectionNames[i]) == 0) { - - size = xSection->iv_size; - offset = xSection->iv_offset; - - printf("%-16s 0x%08x 0x%08x (%d)\n", - g_sectionNames[i], - xSection->iv_offset, xSection->iv_size, xSection->iv_size); - - break; - } - } - - newImage = malloc(size); - - if (newImage == 0) { - fprintf(stderr, "Can't malloc() a buffer for the new image\n"); - exit(1); - } - - memcpy(newImage, (void*)((uint64_t)io_image + offset), size); - - fileFd = open(file, O_CREAT | O_WRONLY | O_TRUNC, 0755); - if (fileFd < 0) { - perror("open() of the fixed section : "); - exit(1); - } - - rc = write(fileFd, newImage, size); - if ((rc < 0) || ((uint32_t)rc != size)) { - perror("write() of fixed section : "); - exit(1); - } - - rc = close(fileFd); - if (rc) { - perror("close() of fixed section : "); - exit(1); - } - - } while (0); - - return rc; - -} - - -// Delete 0 or more sections in order. - -int -deleteSection(const char* i_imageFile, const int i_imageFd, void* io_image, - int i_argc, const char** i_argv) -{ - int newImageFd, sectionId, rc, argc; - const char* section; - const char** argv; - void* newImage; - uint32_t size; - - do { - - // malloc() a buffer for the new image - - rc = sbe_xip_image_size(io_image, &size); - if (rc) break; - - newImage = malloc(size); - - if (newImage == 0) { - fprintf(stderr, "Can't malloc() a buffer for the new image\n"); - exit(1); - } - - - // Copy the image. At this point the original image file must be - // closed. - - memcpy(newImage, io_image, size); - - rc = close(i_imageFd); - if (rc) { - perror("close() of the original image file failed : "); - exit(1); - } - - // Delete the sections in argument order - - for (argc = i_argc, argv = i_argv; argc != 0; argc--, argv++) { - - // Translate the section name to a section Id - - section = *argv; - - for (sectionId = 0; sectionId < SBE_XIP_SECTIONS; sectionId++) { - if (strcmp(section, g_sectionNames[sectionId]) == 0) { - break; - } - } - if (sectionId == SBE_XIP_SECTIONS) { - fprintf(stderr, "Unrecognized section name : '%s;\n", - section); - exit(1); - } - - // Delete the section - - rc = sbe_xip_delete_section(newImage, sectionId); - if (rc) break; - } - if (rc) break; - - // Print the final size of the new image - - rc = sbe_xip_image_size(newImage, &size); - if (rc) break; - - printf("%u\n", size); - - // Now write the new image back to the filesystem - - newImageFd = open(i_imageFile, O_WRONLY | O_TRUNC); - if (newImageFd < 0) { - perror("re-open() of image file failed : "); - exit(1); - } - - rc = write(newImageFd, newImage, size); - if ((rc < 0) || ((uint32_t)rc != size)) { - perror("write() of modified image failed : "); - exit(1); - } - - rc = close(newImageFd); - if (rc) { - perror("close() of modified image failed : "); - exit(1); - } - } while (0); - - return rc; -} - - -// 'TEST' is an undocumented command provided to test the APIs. It searches -// and modifies a copy of the image but puts the image back together as it -// was, then verifies that the the original image and the copy are identical. - -#define BOMB_IF(test) \ - if (test) { \ - fprintf(stderr, "%s:%d : Error in TEST\n", \ - __FILE__, __LINE__); \ - exit(1); \ - } - -#define BOMB_IF_RC \ - if (rc) { \ - fprintf(stderr, "%s:%d : Error in TEST, rc = %s\n", \ - __FILE__, __LINE__, \ - SBE_XIP_ERROR_STRING(g_errorStrings, rc)); \ - exit(1); \ - } - - -int -TEST(void* io_image, const int i_argc, const char** i_argv) -{ - int rc; - uint64_t linkAddress, entryPoint, data, data1, magicKey, entry_offset[2]; - char *key, *revision, *revdup, *longString, *shortString; - void *originalImage, *deleteAppendImage; - uint32_t imageSize; - SbeXipItem item; - SbeXipHeader header; - SbeXipSection section; - //ProcSbeFixed* fixed; - uint32_t tocSize; - - do { - rc = sbe_xip_image_size(io_image, &imageSize); - BOMB_IF_RC; - originalImage = malloc(imageSize); - BOMB_IF(originalImage == 0); - memcpy(originalImage, io_image, imageSize); - - rc = sbe_xip_get_scalar(io_image, "toc_sorted", &data); - BOMB_IF_RC; - BOMB_IF(data != 1); - - rc = sbe_xip_get_scalar(io_image, "image_size", &data); - BOMB_IF_RC; - BOMB_IF(data != (uint64_t)g_imageSize); - - rc = sbe_xip_get_scalar(io_image, "magic", &magicKey); - BOMB_IF_RC; - - switch (magicKey) { - case SBE_BASE_MAGIC: - key = (char*)"proc_sbe_fabricinit_revision"; - rc = sbe_xip_get_string(io_image, key, &revision); - BOMB_IF_RC; - BOMB_IF(strncmp(revision, "1.", 2) != 0); - break; - case SBE_SEEPROM_MAGIC: - key = (char*)""; - // Can't do this test here as the TOC has been stripped - break; - case SBE_CENTAUR_MAGIC: - key = (char*)"cen_sbe_initf_revision"; - rc = sbe_xip_get_string(io_image, key, &revision); - BOMB_IF_RC; - BOMB_IF(strncmp(revision, "1.", 2) != 0); - break; - default: - BOMB_IF(1); - break; - } - - rc = sbe_xip_get_scalar(io_image, "link_address", &linkAddress); - BOMB_IF_RC; - if (magicKey != SBE_SEEPROM_MAGIC) { - rc = sbe_xip_get_scalar(io_image, "entry_point", &entryPoint); - BOMB_IF_RC; - } - rc = sbe_xip_get_scalar(io_image, "entry_offset", &data); - BOMB_IF_RC; - BOMB_IF((magicKey != SBE_SEEPROM_MAGIC) && (entryPoint != (linkAddress + data))); - - rc = - sbe_xip_set_scalar(io_image, "toc_sorted", 0) || - sbe_xip_set_scalar(io_image, "image_size", 0); - BOMB_IF_RC; - - data = 0; - data += (rc = sbe_xip_get_scalar(io_image, "toc_sorted", &data), data); - BOMB_IF_RC; - data += (rc = sbe_xip_get_scalar(io_image, "image_size", &data), data); - BOMB_IF_RC; - BOMB_IF(data != 0); - - // Write back keys found during read check. - - rc = - sbe_xip_set_scalar(io_image, "toc_sorted", 1) || - sbe_xip_set_scalar(io_image, "image_size", g_imageSize); - BOMB_IF_RC; - - // We'll rewrite the revision keyword with a long string and a short - // string, and verify that rewriting is being done correctly. In the - // end we copy the original revision string back in, which is safe - // because the memory allocation for strings does not change when they - // are modified. - - revdup = strdup(revision); - longString = (char*)"A very long string"; - shortString = (char*)"?"; - - if (magicKey != SBE_SEEPROM_MAGIC) { - rc = - sbe_xip_set_string(io_image, key, longString) || - sbe_xip_get_string(io_image, key, &revision); - BOMB_IF_RC; - BOMB_IF((strlen(revision) != strlen(revdup)) || - (strncmp(revision, longString, strlen(revdup)) != 0)); - - rc = - sbe_xip_set_string(io_image, key, shortString) || - sbe_xip_get_string(io_image, key, &revision); - BOMB_IF_RC; - BOMB_IF(strcmp(revision, shortString) != 0); - - memcpy(revision, revdup, strlen(revdup) + 1); - } - - // Use sbe_xip_[read,write]_uint64 to modify the image and restore it - // to its original form. - - rc = sbe_xip_find(io_image, "entry_offset", &item); - BOMB_IF_RC; - rc = sbe_xip_get_scalar(io_image, "entry_offset", &(entry_offset[0])); - BOMB_IF_RC; - - rc = sbe_xip_read_uint64(io_image, item.iv_address, &(entry_offset[1])); - BOMB_IF_RC; - BOMB_IF(entry_offset[0] != entry_offset[1]); - - rc = sbe_xip_write_uint64(io_image, item.iv_address, - 0xdeadbeefdeadc0deull); - BOMB_IF_RC; - rc = sbe_xip_read_uint64(io_image, item.iv_address, &(entry_offset[1])); - BOMB_IF_RC; - BOMB_IF(entry_offset[1] != 0xdeadbeefdeadc0deull); - - rc = sbe_xip_write_uint64(io_image, item.iv_address, entry_offset[0]); - BOMB_IF_RC; - - // Try sbe_xip_get_section against the translated header - - sbe_xip_translate_header(&header, (SbeXipHeader*)io_image); - rc = sbe_xip_get_section(io_image, SBE_XIP_SECTION_TOC, §ion); - BOMB_IF_RC; - BOMB_IF((section.iv_size != - header.iv_section[SBE_XIP_SECTION_TOC].iv_size)); - - - // Make sure the .fixed section access compiles and seems to - // work. Modify an entry via the .fixed and verify it with normal TOC - // access. - - if (magicKey == SBE_SEEPROM_MAGIC) { - - BOMB_IF(0 != 0); - - exit(1); - - rc = sbe_xip_get_scalar(io_image, "proc_sbe_ex_dpll_initf_control", - &data); - BOMB_IF_RC; - //fixed = - //(ProcSbeFixed*)((unsigned long)io_image + SBE_XIP_FIXED_OFFSET); - //fixed->proc_sbe_ex_dpll_initf_control = 0xdeadbeefdeadc0deull; - rc = sbe_xip_get_scalar(io_image, "proc_sbe_ex_dpll_initf_control", - &data1); - BOMB_IF_RC; -#ifdef _BIG_ENDIAN - BOMB_IF(data1 != 0xdeadbeefdeadc0deull); -#else - BOMB_IF(data1 != 0xdec0addeefbeaddeull); -#endif - rc = sbe_xip_set_scalar(io_image, "proc_sbe_ex_dpll_initf_control", - data); - BOMB_IF_RC; - } - - // Temporarily "delete" the .toc section and try to get/set via the - // mini-TOC for .fixed, and make sure that we can't get things that - // are not in the mini-toc. - - tocSize = - ((SbeXipHeader*)io_image)->iv_section[SBE_XIP_SECTION_TOC].iv_size; - - ((SbeXipHeader*)io_image)->iv_section[SBE_XIP_SECTION_TOC].iv_size = - 0; - - rc = sbe_xip_get_scalar(io_image, "proc_sbe_ex_dpll_initf_control", - &data); - rc = sbe_xip_set_scalar(io_image, "proc_sbe_ex_dpll_initf_control", - 0xdeadbeef); - rc = sbe_xip_get_scalar(io_image, "proc_sbe_ex_dpll_initf_control", - &data1); - BOMB_IF(data1 != 0xdeadbeef); - rc = sbe_xip_set_scalar(io_image, "proc_sbe_ex_dpll_initf_control", - data); - BOMB_IF_RC; - - BOMB_IF(sbe_xip_find(io_image, "proc_sbe_ex_dpll_initf", 0) != - SBE_XIP_ITEM_NOT_FOUND); - - ((SbeXipHeader*)io_image)->iv_section[SBE_XIP_SECTION_TOC].iv_size = - tocSize; - - if (magicKey != SBE_SEEPROM_MAGIC) { - BOMB_IF(sbe_xip_find(io_image, "proc_sbe_ex_dpll_initf", 0) != 0); - } - - -#ifdef DEBUG_SBE_XIP_IMAGE - printf("\nYou will see an expected warning below " - "about SBE_XIP_WOULD_OVERFLOW\n" - "It means the TEST is working (not failing)\n\n"); -#endif - - // Finally compare against the original - - BOMB_IF(memcmp(io_image, originalImage, imageSize)); - - } while (0); - - return rc; -} - - -/// Function: pairRingNameAndAddr() to be used w/sbe_xip_map_toc() -/// -/// Brief: Looks for address match for both base and override rings and -/// for multi-chiplet rings. Returns the ring name and other good -/// stuff in the PairingInfo structure upon a match. -/// -/// \param[in] i_image A pointer to an SBE-XIP image in host memory. -/// -/// \param[in] i_item A pointer to the "next" SbeXipItem in the TOC. -/// -/// \param[io] io_pairing A pointer to the structure, PairingInfo. -/// -/// Assumptions: -/// - On input, io_pairing contains -/// - address = the backPtr of the next ring block, -/// - vectorpos = the next vector position, starting from 0,1,2,..,31 and -/// which includes possible override pos. -/// - The TOC is then traversed and each TOC entry is put into i_item. -/// - The backPtr in io_pairing is kept constant until TOC has been exhausted. -/// - On output, io_pairing contains -/// - name = TOC name -/// - isvpd = whether it's a VPD or non-VPD ring -/// - overridable = whether it's an overridable ring -/// - override = whether it's a base or an override ring -/// - In general, we don't know if a ring is a base or an override of if it is a -/// multi-chiplet type. Thus, we first look for a match to the vector in -/// in position zero, then we try position one, then position two, ..., and up -/// to a max of position 31 (which would be an override for ex chiplet 0x1F). -/// -static int pairRingNameAndAddr( void *i_image, const SbeXipItem *i_item, void *io_pairing) -{ - int rc=0,rcLoc=-1; - SbeXipItem tocItem; - PairingInfo *pairingInfo; - RingIdList *ringIdList; - - SBE_XIP_ERROR_STRINGS(g_errorStrings); - - rcLoc = sbe_xip_find( i_image, i_item->iv_id, &tocItem); - if (rcLoc) { - fprintf( stderr, "sbe_xip_find() failed : %s\n", SBE_XIP_ERROR_STRING(g_errorStrings, rcLoc)); - rc = DIS_RING_NAME_ADDR_MATCH_FAILURE; - } - else { - pairingInfo = (PairingInfo*)io_pairing; - // Do a sanity check. - if (pairingInfo->vectorpos>31) { - fprintf( stderr, "vectorpos (=%i) must be between [0;31]\n",pairingInfo->vectorpos); - rc = DIS_RING_NAME_ADDR_MATCH_FAILURE; - } - // Check for match. - // - vectorpos is passed in such that first we look for base match, then for override - // or chiplet range match. - if (tocItem.iv_address == pairingInfo->address-8*pairingInfo->vectorpos && - tocItem.iv_id!=NULL ) { - pairingInfo->name = tocItem.iv_id; - rcLoc = get_vpd_ring_list_entry(pairingInfo->name,0,&ringIdList); - if (!rcLoc) { - // It is a VPD ring...and they never have overrides. - pairingInfo->isvpd = 1; - pairingInfo->overridable = 0; - } - else { - // It is a non-VPD ring...and they all have override capability. - pairingInfo->isvpd = 0; - pairingInfo->overridable = 1; - } - if (pairingInfo->vectorpos==0) - // This can only be a base match. - pairingInfo->override = 0; - else { - // This is not a base match. Investigating further if override. (Note, - // this includes a multi-dim vector with multi-dim override.) - if (pairingInfo->overridable && - 2*(pairingInfo->vectorpos/2)!=pairingInfo->vectorpos) - pairingInfo->override = 1; - else - pairingInfo->override = 0; - } - rc = DIS_RING_NAME_ADDR_MATCH_SUCCESS; - } - } - return rc; -} - -// this function is just defined out, because there is a future need. -#ifdef BLUBBER -/// Function: disassembleSection -/// -/// Brief: Disassembles a section and returns a pointer to a buffer that -/// contains the listing. -/// -/// \param[in] i_image A pointer to an SBE-XIP image in host memory. -/// -/// \param[in] i_argc Additional number of arguments beyond "dis" keyword. -/// -/// \param[in] i_argv Additional arguments beyond "dis" keyword. -/// -/// Assumptions: -/// -int disassembleSection(void *i_image, - int i_argc, - const char **i_argv) -{ - int rc=0, rcSet=0; - uint32_t rcCount=0; - char *disList=NULL; - uint32_t sizeSection=0, nextLinkOffsetBlock=0; - uint32_t sizeBlock=0, sizeData=0, sizeCode=0, sizeData2=0; - uint32_t sizeDisLine=0, sizeList=0, sizeListMax=0; - uint32_t offsetCode=0; - uint8_t typeRingsSection=0; // 0: RS4 1: Wiggle-Flip - uint8_t bSummary=0, bFoundInToc=0; - uint32_t sectionId; - uint64_t backPtr=0, fwdPtr=0; - PairingInfo pairingInfo; - const char *sectionName; - char *ringName; - uint32_t ringSeqNo=0; // Ring sequence location counter. - uint8_t vectorPos,overRidable; - void *nextBlock, *nextSection; - SbeXipHeader hostHeader; - SbeXipSection hostSection; - ImageInlineContext ctx; - ImageInlineDisassembly dis; - char lineDis[LISTING_STRING_SIZE]; - void *hostRs4Container; - uint32_t compressedBits=0, ringLength=0; - double compressionPct=0; - - if (i_argc != 1) { - fprintf(stderr, g_usage); - exit(1); - } - sectionName = i_argv[0]; - - // Determine SBE-XIP section ID from the section name, e.g. - // .loader_text => SBE_XIP_SECTION_LOADER_TEXT - // .text => SBE_XIP_SECTION_TEXT - // .rings => SBE_XIP_SECTION_RINGS - if (strcmp(sectionName, ".header")==0) - sectionId = SBE_XIP_SECTION_HEADER; - else - if (strcmp(sectionName, ".fixed")==0) - sectionId = SBE_XIP_SECTION_FIXED; - else - if (strcmp(sectionName, ".fixed_toc")==0) - sectionId = SBE_XIP_SECTION_FIXED_TOC; - else - if (strcmp(sectionName, ".loader_text")==0) - sectionId = SBE_XIP_SECTION_LOADER_TEXT; - else - if (strcmp(sectionName, ".loader_data")==0) - sectionId = SBE_XIP_SECTION_LOADER_DATA; - else - if (strcmp(sectionName, ".text")==0) - sectionId = SBE_XIP_SECTION_TEXT; - else - if (strcmp(sectionName, ".data")==0) - sectionId = SBE_XIP_SECTION_DATA; - else - if (strcmp(sectionName, ".toc")==0) - sectionId = SBE_XIP_SECTION_TOC; - else - if (strcmp(sectionName, ".strings")==0) - sectionId = SBE_XIP_SECTION_STRINGS; - else - if (strcmp(sectionName, ".base")==0) - sectionId = SBE_XIP_SECTION_BASE; - else - if (strcmp(sectionName, ".baseloader")==0) - sectionId = SBE_XIP_SECTION_BASELOADER; - else - if (strcmp(sectionName, ".rings")==0) - sectionId = SBE_XIP_SECTION_RINGS; - else - if (strcmp(sectionName, ".rings_summary")==0) { - sectionId = SBE_XIP_SECTION_RINGS; - bSummary = 1; - } - else - if (strcmp(sectionName, ".overlays")==0) - sectionId = SBE_XIP_SECTION_OVERLAYS; - else - if (strcmp(sectionName, ".hbbl")==0) - sectionId = SBE_XIP_SECTION_HBBL; - else { - fprintf(stderr,"ERROR : %s is an invalid section name.\n",sectionName); - fprintf(stderr,"Valid <section> names for the 'dis' function are:\n"); - fprintf(stderr,"\t.header\n"); - fprintf(stderr,"\t.fixed\n"); - fprintf(stderr,"\t.fixed_toc\n"); - fprintf(stderr,"\t.loader_text\n"); - fprintf(stderr,"\t.loader_data\n"); - fprintf(stderr,"\t.text\n"); - fprintf(stderr,"\t.data\n"); - fprintf(stderr,"\t.toc\n"); - fprintf(stderr,"\t.strings\n"); - fprintf(stderr,"\t.base\n"); - fprintf(stderr,"\t.baseloader\n"); - fprintf(stderr,"\t.overlays\n"); - fprintf(stderr,"\t.rings\n"); - fprintf(stderr,"\t.rings_summary\n"); - fprintf(stderr,"\t.hbbl\n"); - exit(1); - } - - // Get host header and section pointer. - // - sbe_xip_translate_header( &hostHeader, (SbeXipHeader*)i_image); - rc = sbe_xip_get_section( i_image, sectionId, &hostSection); - if (rc) { - fprintf( stderr, "sbe_xip_get_section() failed : %s\n", SBE_XIP_ERROR_STRING(g_errorStrings, rc)); - return SBE_XIP_DISASSEMBLER_ERROR; - } - sizeSection = hostSection.iv_size; - nextBlock = (void*)(hostSection.iv_offset + (uintptr_t)i_image); - nextSection = (void*)((uint64_t)nextBlock + (uint64_t)sizeSection); - - // Relocatable offset of section at hand. - nextLinkOffsetBlock = (uint32_t)hostHeader.iv_linkAddress + hostSection.iv_offset; - - // Allocate buffer to hold disassembled listing. (Start out with minimum 10k buffer size.) - // - if (sizeSection>10000) - sizeListMax = sizeSection; // Just to use something as an initial guess. - else - sizeListMax = 10000; - disList = (char*)malloc(sizeListMax); - if (disList==NULL) { - fprintf( stderr, "ERROR : malloc() failed.\n"); - fprintf( stderr, "\tMore info: %s\n", DIS_ERROR_STRING(g_errorStringsDis, DIS_MEMORY_ERROR)); - return SBE_XIP_DISASSEMBLER_ERROR; - } - *disList = '\0'; // Make sure the buffer is NULL terminated (though probably not needed.) - sizeList = 0; - - // Create context and point it to image section. - // - rc = image_inline_context_create( &ctx, - nextBlock, - sizeSection, - nextLinkOffsetBlock, - 0); - if (rc) { - fprintf( stderr, "ERROR : %s (rc=%i)\n",image_inline_error_strings[rc],rc); - fprintf( stderr, "\tMore info: %s\n", DIS_ERROR_STRING(g_errorStringsDis, DIS_DISASM_ERROR)); - return SBE_XIP_DISASSEMBLER_ERROR; - } - - while ((uint64_t)nextBlock<(uint64_t)nextSection) { - - // Disassemble sections based on their types and intents. - // - if (sectionId==SBE_XIP_SECTION_RINGS || sectionId==SBE_XIP_SECTION_OVERLAYS) { - // Ring section (with a mix of data and code.) - // ...use BaseRingLayout structure to decode each ring block. - offsetCode = (uint32_t)myRev64(((BaseRingLayout*)nextBlock)->entryOffset); - sizeBlock = myRev32(((BaseRingLayout*)nextBlock)->sizeOfThis); - // ...determine ring type, either RS4 or Wiggle-flip. - if (offsetCode-(myRev32(((BaseRingLayout*)nextBlock)->sizeOfMeta)+3)/4*4>28) { - typeRingsSection = 0; // RS4 w/32-byte header. - sizeData2 = sizeBlock - offsetCode - ASM_RS4_LAUNCH_BUF_SIZE; - } - else - typeRingsSection = 1; // Wiggle-flip w/24-byte header. - // ...get the backPtr and fwdPtr and put at top of disasm listing. - backPtr = myRev64(((BaseRingLayout*)nextBlock)->backItemPtr); - sbe_xip_read_uint64(i_image, - backPtr, - &fwdPtr); - - // Calculate RS4 compression efficiency if RS4 rings. - if (typeRingsSection==0) { - hostRs4Container = (void*)( (uintptr_t)nextBlock + - offsetCode + ASM_RS4_LAUNCH_BUF_SIZE ); - compressedBits = myRev32(((CompressedScanData*)hostRs4Container)->iv_algorithmReserved) * 4; - ringLength = myRev32(((CompressedScanData*)hostRs4Container)->iv_length); - compressionPct = (double)compressedBits / (double)ringLength * 100.0; - } - - // - // Map over TOC or do a targeted search of FIXED_TOC to pair backPtr addr - // with ring name and override and/or vector position (i.e. multi-chiplet). - // - sbe_xip_get_section( i_image, SBE_XIP_SECTION_TOC, &hostSection); - if (hostSection.iv_offset) { - // TOC exists. - pairingInfo.address = backPtr; - // Search for pairing. First exhaust base position (pos=0), then next, then next, ... - for (pairingInfo.vectorpos=0;pairingInfo.vectorpos<32;pairingInfo.vectorpos++) { - rc = sbe_xip_map_toc( i_image, pairRingNameAndAddr, (void*)(&pairingInfo)); - if (rc) - break; - } - if (rc==DIS_RING_NAME_ADDR_MATCH_FAILURE) { - fprintf( stderr,"ERROR : Error associated with sbe_xip_map_toc().\n"); - fprintf( stderr, "\tMore info: %s\n", DIS_ERROR_STRING(g_errorStringsDis, DIS_RING_NAME_ADDR_MATCH_FAILURE)); - return SBE_XIP_DISASSEMBLER_ERROR; - } - ringSeqNo++; - if (rc==DIS_RING_NAME_ADDR_MATCH_SUCCESS) { - bFoundInToc = 1; - ringName = pairingInfo.name; // The ring name matched in pairRingNameAndAddr() - vectorPos = pairingInfo.vectorpos; // The vector position matched in pairRingNameAndAddr() - overRidable = pairingInfo.overridable; // Whether the ring supports on override ring. - if (pairingInfo.override) { - sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, - "# ------------------------------\n# %i.\n# ringName = %s (override)\n# vectorPos = %i\n# overRidable = %i\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n# Compressed Bits = %u\n# Ring Length Bits = %u\n# Compression = %0.2f%%\n", - ringSeqNo, ringName,vectorPos,overRidable,(uint32_t)backPtr,(uint32_t)fwdPtr,compressedBits,ringLength,compressionPct); - } - else { - sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, - "# ------------------------------\n# %i.\n# ringName = %s (base)\n# vectorPos = %i\n# overRidable = %i\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n# Compressed Bits = %u\n# Ring Length Bits = %u\n# Compression = %0.2f%%\n", - ringSeqNo,ringName,vectorPos,overRidable,(uint32_t)backPtr,(uint32_t)fwdPtr,compressedBits,ringLength,compressionPct); - } - } - else { - sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, - "# ------------------------------\n# %i.\n# ringName = Not found (but TOC's available)\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n", - ringSeqNo,(uint32_t)backPtr,(uint32_t)fwdPtr); - } - } - else { - // TOC doesn't exist. First try targeted search of MVPD ring names in FIXED_TOC. - bFoundInToc = 0; // If we find in fixed_toc, then change to 1. - // 2012-11-13: CMO TBD. Try using pairRingNameAndAddr by enabling a sequential - // traversing of each of the MVPD lists inside that function. You'll - // need to call pairRing manually from right here (or from a - // sbe_xip_search_fixed_toc()-like function). Maybe you can add a - // 4th arg to pairRing that is zero by default, meaning it is to be - // used by xip_map_toc(). But if non-zero, it is to be used in a - // traversing manner. Or you could add another member to the - // PairingInfo struct to indirectly pass this info to the function. - // You'd also need to pass two more arguments to get_vpd_ring_list_ - // entry() to indicate sequence number and the MVPD keyword. - // rc = pairRingNameAndAddr(); - // if (rc==DIS_RING_NAME_ADDR_MATCH_SUCCESS) { - // bFoundInToc = 1; - // // Do same as in TOC section above. - // break; - // } - // // OK, so ring name wasn't in TOC nor in FIXED_TOC. That happens if the ring - // // is a non-Mvpd ring and the TOC has been removed, such as in an IPL or - // // Seeprom image. - ringSeqNo++; - if (typeRingsSection==0) { - // RS4 header, which has override info - if (((Rs4RingLayout*)nextBlock)->override==0) { - sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, - "# ------------------------------\n# %i.\n# ringName = Not available (base)\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n# Compressed Bits = %u\n# Ring Length Bits = %u\n# Compression = %0.2f%%\n", - ringSeqNo,(uint32_t)backPtr,(uint32_t)fwdPtr,compressedBits,ringLength,compressionPct); - } - else { - sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, - "# ------------------------------\n# %i.\n# ringName = Not available (override)\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n# Compressed Bits = %u\n# Ring Length Bits = %u\n# Compression = %0.2f%%\n", - ringSeqNo,(uint32_t)backPtr,(uint32_t)fwdPtr,compressedBits,ringLength,compressionPct); - } - } - else { - // WF header, which doesn't have override info - sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, - "# ------------------------------\n# %i.\n# ringName and override = Not available\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n", - ringSeqNo,(uint32_t)backPtr,(uint32_t)fwdPtr); - } - } - sizeList = sizeList + sizeDisLine; - disList = strcat(disList,lineDis); - } - else if ( sectionId==SBE_XIP_SECTION_LOADER_TEXT || - sectionId==SBE_XIP_SECTION_TEXT) { - // Sections that have only code. - offsetCode = 0; - sizeBlock = sizeSection; - } - else { - // Sections that have only data. - offsetCode = sizeSection; - sizeBlock = sizeSection; - } - sizeData = offsetCode; - sizeCode = sizeBlock - offsetCode - sizeData2; - - if (sectionId==SBE_XIP_SECTION_RINGS && bSummary) { - // - // Summarize rings section. - - if (typeRingsSection==0) { // RS4 header. - sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, - "# ddLevel = 0x%02x\n# override= %i\n# sysPhase= %i\n# Block size= %i\n", - myRev32(((Rs4RingLayout*)nextBlock)->ddLevel), - ((Rs4RingLayout*)nextBlock)->override, - ((Rs4RingLayout*)nextBlock)->sysPhase, - sizeBlock); - } - else { // WF header. - if (bFoundInToc) { - sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, - "# override= %i\n# Block size= %i\n", - pairingInfo.override, sizeBlock); - } - else { - sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, - "# override= Not available\n# Block size= %i\n", - sizeBlock); - } - } - sizeList = sizeList + sizeDisLine; - disList = strcat(disList,lineDis); - // Readjust list buffer size, if needed. - if (sizeList > sizeListMax-1000) { - sizeListMax = 2*sizeListMax; - disList = (char*)realloc( (void*)(disList), sizeListMax); - } - - } - else { - // - // Do disassembly. - - // ...data disassembly - if (sizeData>0) { - ctx.options = IMAGE_INLINE_LISTING_MODE | IMAGE_INLINE_DISASSEMBLE_DATA; - do { - rc = image_inline_disassemble( &ctx, &dis); - sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,"%s\n",dis.s); - sizeList = sizeList + sizeDisLine; - disList = strcat(disList,lineDis); - if (rc) { - rcSet = rcSet | 0x1; - sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, - "WARNING: %s (rc=%i) -> Stopping disasm. Check code and sectionID=%i.\n", - image_inline_error_strings[rc],rc,sectionId); - sizeList = sizeList + sizeDisLine; - disList = strcat(disList,lineDis); - } - // Readjust list buffer size, if needed. - if (sizeList > sizeListMax-1000) { - sizeListMax = 2*sizeListMax; - disList = (char*)realloc( (void*)(disList), sizeListMax); - } - } while (rc==0 && ctx.lc<nextLinkOffsetBlock+sizeData); - } - if (rcSet) - rc = 0; - - // ...code disassembly - if (sizeCode>0) { - ctx.options = IMAGE_INLINE_LISTING_MODE; - do { - rc = image_inline_disassemble( &ctx, &dis); - ctx.options = IMAGE_INLINE_LISTING_MODE; - sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,"%s\n",dis.s); - sizeList = sizeList + sizeDisLine; - disList = strcat(disList,lineDis); - if (rc && rcCount<100) { - rcSet = rcSet | 0x2; - rcCount++; - if (sectionId==SBE_XIP_SECTION_RINGS) { - sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, - "WARNING: %s (rc=%i) -> Trying data disasm mode. Check code, xyzRingLayout structures and image section.\n", - image_inline_error_strings[rc],rc); - } - else { - sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, - "WARNING: %s (rc=%i) -> Trying data disasm mode.\n", - image_inline_error_strings[rc],rc); - } - sizeList = sizeList + sizeDisLine; - disList = strcat(disList,lineDis); - ctx.options = IMAGE_INLINE_LISTING_MODE | IMAGE_INLINE_DISASSEMBLE_DATA; - rc = 0; - } - else { - if (rc && rcCount>=1000) { - fprintf(stderr, "Too many disasm warnings. Check output listing.\n"); - fprintf( stderr, "\tMore info: %s\n", DIS_ERROR_STRING(g_errorStringsDis, DIS_TOO_MANY_DISASM_WARNINGS)); - return SBE_XIP_DISASSEMBLER_ERROR; - } - } - // Readjust list buffer size, if needed. - if (sizeList > sizeListMax-1000) { - sizeListMax = 2*sizeListMax; - disList = (char*)realloc( (void*)(disList), sizeListMax); - } - } while (rc==0 && ctx.lc<nextLinkOffsetBlock+sizeData+sizeCode); - } - if (rcSet) - rc = 0; - - // ...data2 disassembly (only done for rings section if RS4 type.) - if (sizeData2>0) { - ctx.options = IMAGE_INLINE_LISTING_MODE | IMAGE_INLINE_DISASSEMBLE_DATA; - do { - rc = image_inline_disassemble( &ctx, &dis); - sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,"%s\n",dis.s); - sizeList = sizeList + sizeDisLine; - disList = strcat(disList,lineDis); - if (rc) { - rcSet = rcSet | 0x4; - sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, - "WARNING: %s (rc=%i) -> Stopping disasm. Check code and sectionID=%i.\n", - image_inline_error_strings[rc],rc,sectionId); - sizeList = sizeList + sizeDisLine; - disList = strcat(disList,lineDis); - } - // Readjust list buffer size, if needed. - if (sizeList > sizeListMax-1000) { - sizeListMax = 2*sizeListMax; - disList = (char*)realloc( (void*)(disList), sizeListMax); - } - } while (rc==0 && ctx.lc<nextLinkOffsetBlock+sizeBlock); - } - if (rcSet) - rc = 0; - - } // End of if (bSummary) condition. - - nextBlock = (void*)((uint64_t)nextBlock + (uint64_t)sizeBlock); - nextLinkOffsetBlock = nextLinkOffsetBlock + sizeBlock; - - } // End of while(nextBlock...) loop. - - // Adjust final buffer size, add 1 for NULL char and print it. - if (disList) { - disList = (char*)realloc( (void*)(disList), sizeList+1); - fprintf(stdout,"%s\n",disList); - free(disList); - } - - if (rcSet) - fprintf( stderr, "INFO : There were some hickups: %s\n", DIS_ERROR_STRING(g_errorStringsDis, DIS_DISASM_TROUBLES)); - - return 0; - -} -#endif - -// open() and mmap() the file - -void -openAndMap(const char* i_fileName, int i_writable, int* o_fd, void** o_image, const uint32_t i_maskIgnores) -{ - int rc, openMode, mmapProt, mmapShared; - struct stat buf; - - if (i_writable) { - openMode = O_RDWR; - mmapProt = PROT_READ | PROT_WRITE; - mmapShared = MAP_SHARED; - } else { - openMode = O_RDONLY; - mmapProt = PROT_READ; - mmapShared = MAP_PRIVATE; - } - - *o_fd = open(i_fileName, openMode); - if (*o_fd < 0) { - perror("open() of the image failed : "); - exit(1); - } - - rc = fstat(*o_fd, &buf); - if (rc) { - perror("fstat() of the image failed : "); - exit(1); - } - g_imageSize = buf.st_size; - - *o_image = mmap(0, g_imageSize, mmapProt, mmapShared, *o_fd, 0); - if (*o_image == MAP_FAILED) { - perror("mmap() of the image failed : "); - exit(1); - } - - if ( !(i_maskIgnores & SBE_XIP_IGNORE_ALL) ) { - rc = sbe_xip_validate2(*o_image, g_imageSize, i_maskIgnores); - if (rc) { - fprintf(stderr, "sbe_xip_validate2() failed : %s\n", - SBE_XIP_ERROR_STRING(g_errorStrings, rc)); - exit(1); - } - } - -} - - -static inline void -openAndMapWritable(const char* i_imageFile, int* o_fd, void** o_image, const uint32_t i_maskIgnores) -{ - openAndMap(i_imageFile, 1, o_fd, o_image, i_maskIgnores); -} - - -static inline void -openAndMapReadOnly(const char* i_imageFile, int* o_fd, void** o_image, const uint32_t i_maskIgnores) -{ - openAndMap(i_imageFile, 0, o_fd, o_image, i_maskIgnores); -} - - -// Parse and execute a pre-tokenized command - -void -command(const char* i_imageFile, const int i_argc, const char** i_argv, const uint32_t i_maskIgnores) -{ - void* image; - int fd, rc = 0; - - if (strcmp(i_argv[0], "normalize") == 0) { - - openAndMapWritable(i_imageFile, &fd, &image, i_maskIgnores); - rc = normalize(image, i_argc - 1, &(i_argv[1]), i_maskIgnores); - - } else if (strcmp(i_argv[0], "set") == 0) { - - openAndMapWritable(i_imageFile, &fd, &image, i_maskIgnores); - rc = set(image, i_argc - 1, &(i_argv[1]), 0); - - } else if (strcmp(i_argv[0], "setv") == 0) { - - openAndMapWritable(i_imageFile, &fd, &image, i_maskIgnores); - rc = set(image, i_argc - 1, &(i_argv[1]), 1); - - } else if (strcmp(i_argv[0], "get") == 0) { - - openAndMapReadOnly(i_imageFile, &fd, &image, i_maskIgnores); - rc = get(image, i_argc - 1, &(i_argv[1]), 0); - - } else if (strcmp(i_argv[0], "getv") == 0) { - - openAndMapReadOnly(i_imageFile, &fd, &image, i_maskIgnores); - rc = get(image, i_argc - 1, &(i_argv[1]), 1); - - } else if (strcmp(i_argv[0], "report") == 0) { - - openAndMapReadOnly(i_imageFile, &fd, &image, i_maskIgnores); - rc = report(image, i_argc - 1, &(i_argv[1])); - - } else if (strcmp(i_argv[0], "append") == 0) { - - openAndMapWritable(i_imageFile, &fd, &image, i_maskIgnores); - rc = append(i_imageFile, fd, image, i_argc - 1, &(i_argv[1])); - - } else if (strcmp(i_argv[0], "extract") == 0) { - - openAndMapWritable(i_imageFile, &fd, &image, i_maskIgnores); - rc = extract(i_imageFile, fd, image, i_argc - 1, &(i_argv[1])); - - } else if (strcmp(i_argv[0], "delete") == 0) { - - openAndMapWritable(i_imageFile, &fd, &image, i_maskIgnores); - rc = deleteSection(i_imageFile, fd, image, i_argc - 1, - &(i_argv[1])); - - } else if (strcmp(i_argv[0], "dis") == 0) { - - //openAndMapReadOnly(i_imageFile, &fd, &image, i_maskIgnores); - //rc = disassembleSection(image, i_argc - 1, &(i_argv[1])); - fprintf(stderr, "not supported\n"); - exit(1); - - - } else if (strcmp(i_argv[0], "TEST") == 0) { - - openAndMapWritable(i_imageFile, &fd, &image, i_maskIgnores); - rc = TEST(image, i_argc - 1, &(i_argv[1])); - - } else { - fprintf(stderr, g_usage); - exit(1); - } - if (rc) { - fprintf(stderr, "Command failed : %s\n", - SBE_XIP_ERROR_STRING(g_errorStrings, rc)); - exit(1); - } -} - - -// Open, map and validate the image, then parse and execute the command. The -// image is memory-mapped read/write, i.e, it may be modified in-place. -// Commands that modify the size of the image will close and recreate the -// file. - -int -main(int argc, const char** argv) -{ - uint8_t argcMin, idxArgvFlagsStart; - uint8_t numFlags=0, idxArgv, bMoreFlags; - uint32_t maskIgnores=0; - - argcMin = 3; - idxArgvFlagsStart = argcMin - 1; // -i flags must start after image file name. - - numFlags = 0; - bMoreFlags = 1; - do { - idxArgv = idxArgvFlagsStart + numFlags; - if (idxArgv <= (argc-1)) { - if (strncmp(argv[idxArgv], "-i", 1) == 0) { - numFlags++; - bMoreFlags = 1; - if (strncmp(argv[idxArgv], "-ifs", 4) == 0) { - maskIgnores = maskIgnores | SBE_XIP_IGNORE_FILE_SIZE; - } - else - if (strncmp(argv[idxArgv], "-iv", 3) == 0) { - maskIgnores = maskIgnores | SBE_XIP_IGNORE_ALL; - } - else { - fprintf(stderr, g_usage); - fprintf(stderr, "\n"); - fprintf(stderr,"argv[%i]=%s is an unsupported flag.",idxArgv,argv[idxArgv]); - fprintf(stderr,"See top of above help menu for supported flags.\n"); - exit(1); - } - } - else - bMoreFlags = 0; - } - else { - bMoreFlags = 0; - break; - } - } while (bMoreFlags); - - if ((argc < (argcMin+numFlags)) || - (strncmp(argv[1], "-h", 2) == 0) || - (strncmp(argv[1], "--h", 3) == 0) ) { - fprintf(stderr, g_usage); - exit(1); - } - - command(argv[1], argc - idxArgv, &(argv[idxArgv]), maskIgnores); - - return 0; -} |