1 /* IBM_PROLOG_BEGIN_TAG                                                   */
2 /* This is an automatically generated prolog.                             */
3 /*                                                                        */
4 /* $Source: src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/sbe_xip_image.h $ */
5 /*                                                                        */
6 /* OpenPOWER HostBoot Project                                             */
7 /*                                                                        */
8 /* Contributors Listed Below - COPYRIGHT 2012,2015                        */
9 /* [+] International Business Machines Corp.                              */
10 /*                                                                        */
11 /*                                                                        */
12 /* Licensed under the Apache License, Version 2.0 (the "License");        */
13 /* you may not use this file except in compliance with the License.       */
14 /* You may obtain a copy of the License at                                */
15 /*                                                                        */
16 /*     http://www.apache.org/licenses/LICENSE-2.0                         */
17 /*                                                                        */
18 /* Unless required by applicable law or agreed to in writing, software    */
19 /* distributed under the License is distributed on an "AS IS" BASIS,      */
20 /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
21 /* implied. See the License for the specific language governing           */
22 /* permissions and limitations under the License.                         */
23 /*                                                                        */
24 /* IBM_PROLOG_END_TAG                                                     */
25 #ifndef __SBE_XIP_IMAGE_H
26 #define __SBE_XIP_IMAGE_H
27 
28 // $Id: sbe_xip_image.h,v 1.26 2015/07/29 23:40:17 cmolsen Exp $
29 // $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/sbe/sbe_xip_image.h,v $
30 //-----------------------------------------------------------------------------
31 // *! (C) Copyright International Business Machines Corp. 2011
32 // *! All Rights Reserved -- Property of IBM
33 // *! ***  ***
34 //-----------------------------------------------------------------------------
35 // *! OWNER NAME: Bishop Brock          Email: bcbrock@us.ibm.com
36 //------------------------------------------------------------------------------
37 
38 /// \file sbe_xip_image.h
39 /// \brief Everything related to creating and manipulating SBE-XIP binary
40 /// images.
41 
42 #include "fapi_sbe_common.H"
43 
44 /// Current version (fields, layout, sections) of the SBE_XIP header
45 ///
46 /// If any changes are made to this file or to sbe_xip_header.H, please update
47 /// the header version and follow-up on all of the error messages.
48 
49 #define SBE_XIP_HEADER_VERSION 8
50 
51 /// \defgroup sbe_xip_magic_numbers SBE-XIP magic numbers
52 ///
53 /// An SBE-XIP magic number is a 64-bit constant.  The 4 high-order bytes
54 /// contain the ASCII characters "XIP " and identify the image as an SBE-XIP
55 /// image, while the 4 low-order bytes identify the type of the image.
56 ///
57 /// @{
58 
59 #define SBE_XIP_MAGIC     0x58495020               // "XIP "
60 #define SBE_BASE_MAGIC    ULL(0x5849502042415345)  // "XIP BASE"
61 #define SBE_SEEPROM_MAGIC ULL(0x584950205345504d)  // "XIP SEPM"
62 #define SBE_CENTAUR_MAGIC ULL(0x58495020434e5452)  // "XIP CNTR"
63 
64 /// @}
65 
66 
67 /// \defgroup sbe_xip_sections SBE-XIP Image Section Indexes
68 ///
69 /// These constants define the order that the SbeXipSection structures appear
70 /// in the header, which is not necessarily the order the sections appear in
71 /// the binary image.  Given that SBE-XIP image contents are tightly
72 /// controlled, we use this simple indexing scheme for the allowed sections
73 /// rather than a more general approach, e.g., allowing arbitrary sections
74 /// identified by their names.
75 ///
76 /// @{
77 
78 // -*- DO NOT REORDER OR EDIT THIS SET OF CONSTANTS WITHOUT ALSO EDITING -*-
79 // -*- THE ASSEMBLER LAYOUT IN sbe_xip_header.H.                         -*-
80 
81 #define SBE_XIP_SECTION_HEADER      0
82 #define SBE_XIP_SECTION_FIXED       1
83 #define SBE_XIP_SECTION_FIXED_TOC   2
84 #define SBE_XIP_SECTION_IPL_TEXT    3
85 #define SBE_XIP_SECTION_IPL_DATA    4
86 #define SBE_XIP_SECTION_TEXT        5
87 #define SBE_XIP_SECTION_DATA        6
88 #define SBE_XIP_SECTION_TOC         7
89 #define SBE_XIP_SECTION_STRINGS     8
90 #define SBE_XIP_SECTION_HALT        9
91 #define SBE_XIP_SECTION_PIBMEM0    10
92 #define SBE_XIP_SECTION_DCRINGS    11
93 #define SBE_XIP_SECTION_RINGS      12
94 #define SBE_XIP_SECTION_SLW        13
95 #define SBE_XIP_SECTION_FIT        14
96 #define SBE_XIP_SECTION_FFDC       15
97 
98 #define SBE_XIP_SECTIONS 16
99 
100 /// @}
101 
102 
103 /// \defgroup sbe_xip_validate() ignore masks.
104 ///
105 /// These defines, when matched in sbe_xip_validate(), cause the validation
106 /// to skip the check of the corresponding property. The purpose is to more
107 /// effectively debug images that may be damaged and which have excess info
108 /// before or after the image. The latter will be the case when dumping the
109 /// image as a memory block without knowing where the image starts and ends.
110 ///
111 /// @{
112 
113 #define SBE_XIP_IGNORE_FILE_SIZE (uint32_t)0x00000001
114 #define SBE_XIP_IGNORE_ALL       (uint32_t)0x80000000
115 
116 /// @}
117 
118 
119 #ifndef __ASSEMBLER__
120 
121 /// Applications can expand this macro to create an array of section names.
122 #define SBE_XIP_SECTION_NAMES(var)              \
123     const char* var[] = {                       \
124         ".header",                              \
125         ".fixed",                               \
126         ".fixed_toc",                           \
127         ".ipl_text",                            \
128         ".ipl_data",                            \
129         ".text",                                \
130         ".data",                                \
131         ".toc",                                 \
132         ".strings",                             \
133         ".halt",                                \
134         ".pibmem0",                             \
135         ".dcrings",                             \
136         ".rings",                               \
137         ".slw",                                 \
138         ".fit",                                 \
139         ".ffdc",                                \
140     }
141 
142 /// Applications can use this macro to safely index the array of section
143 /// names.
144 #define SBE_XIP_SECTION_NAME(var, n)                                   \
145     ((((n) < 0) || ((n) > (int)(sizeof(var) / sizeof(char*)))) ?        \
146      "Bug : Invalid SBE-XIP section name" : var[n])
147 
148 
149 #endif  /* __ASSEMBLER__ */
150 
151 
152 /// Maximum section alignment for SBE-XIP sections
153 #define SBE_XIP_MAX_SECTION_ALIGNMENT 128
154 
155 /// \defgroup sbe_xip_toc_types SBE-XIP Table of Contents data types
156 ///
157 /// These are the data types stored in the \a iv_type field of the SbeXipToc
158 /// objects.  These must be defined as manifest constants because they are
159 /// required to be recognized as manifest constants in C (as opposed to C++)
160 /// code.
161 ///
162 /// NB: The 0x0 code is purposefully left undefined to catch bugs.
163 ///
164 /// @{
165 
166 /// Data is a single unsigned byte
167 #define SBE_XIP_UINT8 0x01
168 
169 /// Data is a 32-bit unsigned integer
170 #define SBE_XIP_UINT32 0x02
171 
172 /// Data is a 64-bit unsigned integer
173 #define SBE_XIP_UINT64 0x03
174 
175 /// Data is a 0-byte terminated ASCII string
176 #define SBE_XIP_STRING 0x04
177 
178 /// Data is an address
179 #define SBE_XIP_ADDRESS 0x05
180 
181 /// The maximum type number
182 #define SBE_XIP_MAX_TYPE_INDEX 0x05
183 
184 /// Applications can expand this macro to get access to string forms of the
185 /// SBE-XIP data types if desired.
186 #define SBE_XIP_TYPE_STRINGS(var)               \
187     const char* var[] = {                       \
188         "Illegal 0 Code",                       \
189         "SBE_XIP_UINT8",                        \
190         "SBE_XIP_UINT32",                       \
191         "SBE_XIP_UINT64",                       \
192         "SBE_XIP_STRING",                       \
193         "SBE_XIP_ADDRESS",                      \
194     }
195 
196 /// Applications can expand this macro to get access to abbreviated string
197 /// forms of the SBE-XIP data types if desired.
198 #define SBE_XIP_TYPE_ABBREVS(var)               \
199     const char* var[] = {                       \
200         "Illegal 0 Code",                       \
201         "u8 ",                                  \
202         "u32",                                  \
203         "u64",                                  \
204         "str",                                  \
205         "adr",                                  \
206     }
207 
208 /// Applications can use this macro to safely index either array of SBE-XIP
209 /// type strings.
210 #define SBE_XIP_TYPE_STRING(var, n)                     \
211     (((n) > (sizeof(var) / sizeof(char*))) ?            \
212      "Invalid SBE-XIP type specification" : var[n])
213 
214 /// @}
215 
216 
217 /// Final alignment constraint for SBE-XIP images.
218 ///
219 /// PORE images are required to be multiples of 8 bytes in length, to
220 /// guarantee that the PoreVe will be able to complete any 8-byte load/store.
221 #define SBE_XIP_FINAL_ALIGNMENT 8
222 
223 
224 ////////////////////////////////////////////////////////////////////////////
225 // C Definitions
226 ////////////////////////////////////////////////////////////////////////////
227 
228 #ifndef __ASSEMBLER__
229 
230 #include <stdint.h>
231 
232 #ifdef __cplusplus
233 extern "C" {
234 #endif
235 #if 0
236 } /* So __cplusplus doesn't mess w/auto-indent */
237 #endif
238 
239 /// SBE-XIP Section information
240 ///
241 /// This structure defines the data layout of section table entries in the
242 /// SBE-XIP image header.
243 
244 // -*- DO NOT REORDER OR EDIT THIS STRUCTURE DEFINITION WITHOUT ALSO    -*-
245 // -*- EDITING THE ASSEMBLER LAYOUT IN sbe_xip_header.H                 -*-
246 
247 typedef struct {
248 
249     /// The offset (in bytes) of the section from the beginning of the image
250     ///
251     /// In normalized images the section offset will always be 0 if the
252     /// section size is also 0.
253     uint32_t iv_offset;
254 
255     /// The size of the section in bytes, exclusive of alignment padding
256     ///
257     /// This is the size of the program-significant data in the section,
258     /// exclusive of any alignment padding or reserved or extra space.  The
259     /// alignment padding (reserved space) is not represented explicitly, but
260     /// is only implied by the offset of any subsequent non-empty section, or
261     /// in the case of the final section in the image, the image size.
262     ///
263     /// Regardless of the \a iv_offset, if the \a iv_size of a section is 0 it
264     /// should be considered "not present" in the image.  In normalized images
265     /// the section offset will always be 0 if the section size is also 0.
266     uint32_t iv_size;
267 
268     /// The required initial alignment for the section offset
269     ///
270     /// The PORE and the applications using SBE-XIP images have strict
271     /// alignment/padding requirements.  The PORE does not handle any type of
272     /// unaligned instruction or data fetches.  Some sections and subsections
273     /// must also be POWER cache-line aligned. The \a iv_alignment applies to
274     /// the first byte of the section. PORE images are also required to be
275     /// multiples of 8 bytes in length, to guarantee that the PoreVe will be
276     /// able to complete any 8-byte load/store.  These constraints are checked
277     /// by sbe_xip_validate() and enforced by sbe_xip_append(). The alignment
278     /// constraints may force a section to be padded, which may create "holes"
279     /// in the image as explained in the comments for the \a iv_size field.
280     ///
281     /// Note that alignment constraints are always checked relative to the
282     /// first byte of the image for in-memory images, not relative to the host
283     /// address. Alignment specifications are required to be a power-of-2.
284     uint8_t iv_alignment;
285 
286     /// Reserved structure alignment padding; Pad to 12 bytes
287     uint8_t iv_reserved8[3];
288 
289 } SbeXipSection;
290 
291 /// The SbeXipSection structure is created by assembler code and is expected
292 /// to have the same size in C code.  This constraint is checked in
293 /// sbe_xip_validate().
294 #define SIZE_OF_SBE_XIP_SECTION 12
295 
296 
297 /// SBE-XIP binary image header
298 ///
299 /// This header occupies the initial bytes of an SBE-XIP binary image.
300 /// The header contents are documented here, however the structure is actually
301 /// defined in the file sbe_xip_header.S, and these two definitions must be
302 /// kept consistent.
303 ///
304 /// The header is a fixed-format representation of the most critical
305 /// information about the image.  The large majority of information about the
306 /// image and its contents are available through the searchable table of
307 /// contents. PORE code itself normally accesses the data directly through
308 /// global symbols.
309 ///
310 /// The header only contains information 1) required by OTPROM code (e.g., the
311 /// entry point); 2) required by search and updating APIs (e.g., the
312 /// locations and sizes of all of the sections.); a few pieces of critical
313 /// meta-data (e.g., information about the image build process).
314 ///
315 /// Any entries that are accessed by PORE code are required to be 64 bits, and
316 /// will appear at the beginning of the header.
317 ///
318 /// The header also contains bytewise offsets and sizes of all of the sections
319 /// that are assembled to complete the image.  The offsets are relative to the
320 /// start of the image (where the header is loaded).  The sizes include any
321 /// padding inserted by the link editor to guarantee section alignment.
322 ///
323 /// Every field of the header is also accesssible through the searchable table
324 /// of contents as documented in sbe_xip_header.S.
325 
326 // -*- DO NOT REORDER OR EDIT THIS STRUCTURE DEFINITION WITHOUT ALSO     -*-
327 // -*- EDITING THE ASSEMBLER LAYOUT IN sbe_xip_header.S, AND WITHOUT     -*-
328 // -*- UPDATING THE sbe_xip_translate_header() API IN sbe_xip_image.c.   -*-
329 
330 typedef struct {
331 
332     //////////////////////////////////////////////////////////////////////
333     // Identification - 8-byte aligned; 8 entries
334     //////////////////////////////////////////////////////////////////////
335 
336     /// Contains SBE_XIP_MAGIC to identify an SBE-XIP image
337     uint64_t iv_magic;
338 
339     /// The offset of the SBE-XIP entry point from the start of the image
340     uint64_t iv_entryOffset;
341 
342     /// The base address used to link the image, as a full relocatable PORE
343     /// address
344     uint64_t iv_linkAddress;
345 
346     /// PTS version
347     uint64_t iv_ptsVersion;
348 
349     /// Reserved for future expansion
350     uint64_t iv_reserved64[4];
351 
352     //////////////////////////////////////////////////////////////////////
353     // Section Table - 4-byte aligned; 16 entries
354     //////////////////////////////////////////////////////////////////////
355 
356     SbeXipSection iv_section[SBE_XIP_SECTIONS];
357 
358     //////////////////////////////////////////////////////////////////////
359     // Other information - 4-byte aligned; 8 entries
360     //////////////////////////////////////////////////////////////////////
361 
362     /// The size of the image (including padding) in bytes
363     uint32_t iv_imageSize;
364 
365     /// Build date generated by `date +%Y%m%d`, e.g., 20110630
366     uint32_t iv_buildDate;
367 
368     /// Build time generated by `date +%H%M`, e.g., 0756
369     uint32_t iv_buildTime;
370 
371     /// Reserved for future expansion
372     uint32_t iv_reserved32[5];
373 
374     //////////////////////////////////////////////////////////////////////
375     // Other Information - 1-byte aligned; 8 entries
376     //////////////////////////////////////////////////////////////////////
377 
378     /// Header format version number
379     uint8_t iv_headerVersion;
380 
381     /// Indicates whether the image has been normalized (0/1)
382     uint8_t iv_normalized;
383 
384     /// Indicates whether the TOC has been sorted to speed searching (0/1)
385     uint8_t iv_tocSorted;
386 
387     /// Reserved for future expansion
388     uint8_t iv_reserved8[5];
389 
390     //////////////////////////////////////////////////////////////////////
391     // Strings; 64 characters allocated
392     //////////////////////////////////////////////////////////////////////
393 
394     /// Build user, generated by `id -un`
395     char iv_buildUser[16];
396 
397     /// Build host, generated by `hostname`
398     char iv_buildHost[24];
399 
400     /// Reserved for future expansion
401     char iv_reservedChar[24];
402 
403 } SbeXipHeader;
404 
405 
406 /// A C-structure form of the SBE-XIP Table of Contents (TOC) entries
407 ///
408 /// The .toc section consists entirely of an array of these structures.
409 /// TOC entries are never accessed by PORE code.
410 ///
411 /// These structures store indexing information for global data required to be
412 /// manipulated by external tools.  The actual data is usually allocated in a
413 /// data section and manipulated by the SBE code using global or local symbol
414 /// names.  Each TOC entry contains a pointer to a keyword string naming the
415 /// data, the address of the data (or the data itself), the data type,
416 /// meta-information about the data, and for vectors the vector size.
417 
418 // -*- DO NOT REORDER OR EDIT THIS STRUCTURE DEFINITION WITHOUT ALSO     -*-
419 // -*- EDITING THE ASSEMBLER MACROS (BELOW) THAT CREATE THE TABLE OF     -*-
420 // -*- CONTENTS ENTRIES.                                                 -*-
421 
422 typedef struct {
423 
424     /// A pointer to a 0-byte terminated ASCII string identifying the data.
425     ///
426     /// When allocated by the .xip_toc macro this is a pointer to the string
427     /// form of the symbol name for the global or local symbol associated with
428     /// the data which is allocated in the .strings section. This pointer is
429     /// not aligned.
430     ///
431     /// When the image is normalized this pointer is replaced by the offset of
432     /// the string in the .strings section.
433     uint32_t iv_id;
434 
435     /// A 32-bit pointer locating the data
436     ///
437     /// This field is initially populated by the link editor.  For scalar,
438     /// vector and string types this is the final relocated address of the
439     /// first byte of the data.  For address types, this is the relocated
440     /// address.  When the image is normalized, these addresses are converted
441     /// into the equivalent offsets from the beginning of the section holding
442     /// the data.
443     uint32_t iv_data;
444 
445     /// The type of the data; See \ref sbe_xip_toc_types.
446     uint8_t iv_type;
447 
448     /// The section containing the data; See \ref sbe_xip_sections.
449     uint8_t iv_section;
450 
451     /// The number of elements for vector types, otherwise 1 for scalar types
452     /// and addresses.
453     ///
454     /// Vectors are naturally limited in size, e.g. to the number of cores,
455     /// chips in a node, DD-levels etc.  If \a iv_elements is 0 then no bounds
456     /// checking is done on get/set accesses of the data.
457     uint8_t iv_elements;
458 
459     /// Structure alignment padding; Pad to 12 bytes
460     uint8_t iv_pad;
461 
462 } SbeXipToc;
463 
464 /// The SbeXipToc structure is created by assembler code and is expected
465 /// to have the same size in C code.  This constraint is checked in
466 /// sbe_xip_validate().
467 #define SIZE_OF_SBE_XIP_TOC 12
468 
469 
470 /// A C-structure form of hashed SBE-XIP Table of Contents (TOC) entries
471 ///
472 /// This structure was introduced in order to allow a small TOC for the .fixed
473 /// section to support minimum-sized SEEPROM images in which the global TOC
474 /// and all strings have been stripped out.  In this structure the index
475 /// string has been replaced by a 32-bit hash, and there is no longer a record
476 /// of the original data name other then the hash.  The section of the data is
477 /// assumed to be .fixed, with a maximum 16-bit offset.
478 ///
479 /// These structures are created when entries are made in the .fixed section.
480 /// They are created empty, then filled in during image normalization.
481 ///
482 /// This structure allows the sbe_xip_get*() and sbe_xip_set*() APIs to work
483 /// even on highly-stripped SEEPROM images.
484 
485 typedef struct {
486 
487     /// A 32-bit hash (FNV-1a) of the Id string.
488     uint32_t iv_hash;
489 
490     /// The offset in bytes from the start of the (implied) section of the data
491     uint16_t iv_offset;
492 
493     /// The type of the data; See \ref sbe_xip_toc_types.
494     uint8_t iv_type;
495 
496     /// The number of elements for vector types, otherwise 1 for scalar types
497     /// and addresses.
498     ///
499     /// Vectors are naturally limited in size, e.g. to the number of cores,
500     /// chips in a node, DD-levels etc.  If \a iv_elements is 0 then no bounds
501     /// checking is done on get/set accesses of the data.
502     uint8_t iv_elements;
503 
504 } SbeXipHashedToc;
505 
506 /// The SbeXipHashedToc structure is created by assembler code and is expected
507 /// to have the same size in C code.  This constraint is checked in
508 /// sbe_xip_validate().
509 #define SIZE_OF_SBE_XIP_HASHED_TOC 8
510 
511 
512 /// A decoded TOC entry for use by applications
513 ///
514 /// This structure is a decoded form of a normalized TOC entry, filled in by
515 /// the sbe_xip_decode_toc() and sbe_xip_find() APIs.  This structure is
516 /// always returned with data elements in host-endian format.
517 ///
518 /// In the event that the TOC has been removed from the image, this structure
519 /// will also be returned by sbe_xip_find() with information populated from
520 /// the .fixed_toc section if possible.  In this case the field \a iv_partial
521 /// will be set and only the fields \a iv_address, \a iv_imageData, \a iv_type
522 /// and \a iv_elements will be populated (all other fields will be set to 0).
523 ///
524 /// \note Only special-purpose applications will ever need to use this
525 /// structure given that the higher-level APIs sbe_xip_get_*() and
526 /// sbe_xip_set_*() are provided and should be used if possible, especially
527 /// given that the information may be truncated as described above.
528 
529 typedef struct {
530 
531     /// A pointer to the associated TOC entry as it exists in the image
532     ///
533     ///  If \a iv_partial is set this field is returned as 0.
534     SbeXipToc* iv_toc;
535 
536     /// The full relocatable PORE address
537     ///
538     /// All relocatable addresses are computed from the \a iv_linkAddress
539     /// stored in the header. For scalar and string data, this is the
540     /// relocatable address of the data.  For address-only entries, this is
541     /// the indexed address itself.
542     uint64_t iv_address;
543 
544     /// A host pointer to the first byte of text or data within the image
545     ///
546     /// For scalar or string types this is a host pointer to the first byte of
547     /// the data.  For code pointers (addresses) this is host pointer to the
548     /// first byte of code.  Note that any use of this field requires the
549     /// caller to handle conversion of the data to host endian-ness if
550     /// required.  Only 8-bit and string data can be used directly on all
551     /// hosts.
552     void* iv_imageData;
553 
554     /// The item name
555     ///
556     /// This is a pointer in host memory to a string that names the TOC entry
557     /// requested.  This field is set to a pointer to the ID string of the TOC
558     /// entry inside the image. If \a iv_partial is set this field is returned
559     /// as 0.
560     char* iv_id;
561 
562     /// The data type, one of the SBE_XIP_* constants
563     uint8_t iv_type;
564 
565     /// The number of elements in a vector
566     ///
567     /// This field is set from the TOC entry when the TOC entry is
568     /// decoded. This value is stored as 1 for scalar declarations, and may be
569     /// set to 0 for vectors with large or undeclared sizes.  Otherwise it is
570     /// used to bounds check indexed accesses.
571     uint8_t iv_elements;
572 
573     /// Is this record only partially populated?
574     ///
575     /// This field is set to 0 normally, and only set to 1 if a lookup is made
576     /// in an image that only has the fixed TOC and the requested Id hashes to
577     /// the fixed TOC.
578     uint8_t iv_partial;
579 
580 } SbeXipItem;
581 
582 
583 /// Prototype entry in the .halt section
584 ///
585 /// The .halt section is generated by the 'reqhalt' macro.  This structure
586 /// associates the address of each halt with the string form of the FAPI
587 /// return code associated with the halt.  The string form is used because the
588 /// FAPI error return code is not constant.  The .halt section is 4-byte
589 /// aligned, and each address/string entry is always padded to a multiple of 4
590 /// bytes.
591 ///
592 /// In the .halt section the \a iv_string may be any length, thus the size of
593 /// each actual record is variable (although guaranteed to always be a
594 /// multiple of 4 bytes). Although the C compiler might natuarlly align
595 /// instances of this structure on a 64-bit boundary, the APIs that allow
596 /// access to the .halt section assume that the underlying machine can do
597 /// non-aligned loads from a pointer to this structure.
598 
599 typedef struct {
600 
601     /// The 64-bit relocatable address of the halt
602     ///
603     /// This is the address found in the PC (Status Register bits 16:63) when
604     /// the PORE halts.  The full 64-bit form is used rather than the simple
605     /// 32-bit offset to support merging SEEPROM and PIBMEM .halt sections in
606     /// the SEEPROM IPL images.
607     uint64_t iv_address;
608 
609     /// A C-prototype for a variable-length 0-terminated ASCII string
610     ///
611     /// This is a prototype only to simplify C programming.  The actual string
612     /// may be any length.
613     char iv_string[4];
614 
615 } SbeXipHalt;
616 
617 
618 /// Validate an SBE-XIP image
619 ///
620 /// \param[in] i_image A pointer to an SBE-XIP image in host memory.
621 ///
622 /// \param[in] i_size The putative size of the image
623 ///
624 /// \param[in] i_maskIgnores Array of ignore bits representing which properties
625 /// should not be checked for in sbe_xip_validate2().
626 ///
627 /// This API should be called first by all applications that manipulate
628 /// SBE-XIP images in host memory.  The magic number is validated, and
629 /// the image is checked for consistency of the section table and table of
630 /// contents.  The \a iv_imageSize field of the header must also match the
631 /// provided \a i_size parameter.  Validation does not modify the image.
632 ///
633 /// \retval 0 Success
634 ///
635 /// \retval non-0 See \ref sbe_xip_image_errors
636 int
637 sbe_xip_validate(void* i_image, const uint32_t i_size);
638 
639 int
640 sbe_xip_validate2(void* i_image, const uint32_t i_size, const uint32_t i_maskIgnores);
641 
642 
643 /// Normalize the SBE-XIP image
644 ///
645 /// \param[in] io_image A pointer to an SBE-XIP image in host memory.  The
646 /// image is assumed to be consistent with the information contained in the
647 /// header regarding the presence of and sizes of all sections.
648 ///
649 /// SBE-XIP images must be normalized before any other APIs are allowed to
650 /// operate on the image.  Since normalization modifies the image, an explicit
651 /// call to normalize the image is required.  Briefly, normalization modifies
652 /// the TOC entries created by the final link to simplify search, updates,
653 /// modification and relocation of the image.  Normalization is explained in
654 /// the written documentation of the SBE-XIP binary format. Normalization does
655 /// not modify the size of the image.
656 ///
657 /// \retval 0 Success
658 ///
659 /// \retval non-0 See \ref sbe_xip_image_errors
660 int
661 sbe_xip_normalize(void* io_image);
662 
663 
664 /// Return the size of an SBE-XIP image from the image header
665 ///
666 /// \param[in] i_image A pointer to an SBE-XIP image in host memory.  The
667 /// image is assumed to be consistent with the information contained in the
668 /// header regarding the presence of and sizes of all sections.
669 ///
670 /// \param[out] o_size A pointer to a variable returned as the size of the
671 /// image in bytes, as recorded in the image header.
672 ///
673 /// \retval 0 Success
674 ///
675 /// \retval non-0 See \ref sbe_xip_image_errors
676 int
677 sbe_xip_image_size(void* i_image, uint32_t* o_size);
678 
679 
680 /// Locate a section table entry and translate into host format
681 ///
682 /// \param[in] i_image A pointer to an SBE-XIP image in host memory.
683 ///
684 /// \param[in] i_sectionId Identifies the section to be queried.  See \ref
685 /// sbe_xip_sections.
686 ///
687 /// \param[out] o_hostSection Updated to contain the section table entry
688 /// translated to host byte order.
689 ///
690 /// \retval 0 Success
691 ///
692 /// \retval non-0 See \ref sbe_xip_image_errors
693 int
694 sbe_xip_get_section(const void* i_image,
695                     const int i_sectionId,
696                     SbeXipSection* o_hostSection);
697 
698 
699 /// Endian translation of an SbeXipHeader object
700 ///
701 /// \param[out] o_hostHeader The destination object.
702 ///
703 /// \param[in] i_imageHeader The source object.
704 ///
705 /// Translation of a SbeXipHeader includes translation of all data members
706 /// including traslation of the embedded section table.  This translation
707 /// works even if \a o_src == \a o_dest, i.e., in the destructive case.
708 void
709 sbe_xip_translate_header(SbeXipHeader* o_hostHeader,
710                          const SbeXipHeader* i_imageHeader);
711 
712 
713 /// Get scalar data from an SBE-XIP image
714 ///
715 /// \param[in] i_image A pointer to an SBE-XIP image in host memory.  The
716 /// image is assumed to be consistent with the information contained in the
717 /// header regarding the presence of and sizes of all sections.  The image is
718 /// also required to have been normalized.
719 ///
720 /// \param[in] i_id A pointer to a 0-terminated ASCII string naming the item
721 /// requested.
722 ///
723 /// \param[out] o_data A pointer to an 8-byte integer to receive the scalar
724 /// data. Assuming the item is located this variable is assigned by the call.
725 /// In the event of an error the final state of \a o_data is not specified.
726 ///
727 /// This API searches the SBE-XIP Table of Contents (TOC) for the item named
728 /// \a i_id, assigning \a o_data from the image if the item is found and is a
729 /// scalar value.  Scalar values include 8- 32- and 64-bit integers and PORE
730 /// addresses.  Image data smaller than 64 bits are extracted as unsigned
731 /// types, and it is the caller's responsibility to cast or convert the
732 /// returned data as appropriate.
733 ///
734 /// \retval 0 Success
735 ///
736 /// \retval non-0 See \ref sbe_xip_image_errors
737 int
738 sbe_xip_get_scalar(void *i_image, const char* i_id, uint64_t* o_data);
739 
740 
741 /// Get an integral element from a vector held in an SBE-XIP image
742 ///
743 /// \param[in] i_image A pointer to an SBE-XIP image in host memory.  The
744 /// image is assumed to be consistent with the information contained in the
745 /// header regarding the presence of and sizes of all sections.  The image is
746 /// also required to have been normalized.
747 ///
748 /// \param[in] i_id A pointer to a 0-terminated ASCII string naming the item
749 /// requested.
750 ///
751 /// \param[in] i_index  The index of the vector element to return.
752 ///
753 /// \param[out] o_data A pointer to an 8-byte integer to receive the
754 /// data. Assuming the item is located this variable is assigned by the call.
755 /// In the event of an error the final state of \a o_data is not specified.
756 ///
757 /// This API searches the SBE-XIP Table of Contents (TOC) for the \a i_index
758 /// element of the item named \a i_id, assigning \a o_data from the image if
759 /// the item is found, is a vector of an integral type, and the \a i_index is
760 /// in bounds.  Vector elements smaller than 64 bits are extracted as unsigned
761 /// types, and it is the caller's responsibility to cast or convert the
762 /// returned data as appropriate.
763 ///
764 /// \retval 0 Success
765 ///
766 /// \retval non-0 See \ref sbe_xip_image_errors
767 int
768 sbe_xip_get_element(void *i_image,
769                     const char* i_id,
770                     const uint32_t i_index,
771                     uint64_t* o_data);
772 
773 
774 /// Get string data from an SBE-XIP image
775 ///
776 /// \param[in] i_image A pointer to an SBE-XIP image in host memory.  The
777 /// image is assumed to be consistent with the information contained in the
778 /// header regarding the presence of and sizes of all sections.  The image is
779 /// also required to have been normalized.
780 ///
781 /// \param[in] i_id A pointer to a 0-terminated ASCII string naming the item
782 /// requested.
783 ///
784 /// \param[out] o_data A pointer to a character pointer.  Assuming the
785 /// item is located this variable is assigned by the call to point to the
786 /// string as it exists in the \a i_image.  In the event of an error the final
787 /// state of \a o_data is not specified.
788 ///
789 /// This API searches the SBE-XIP Table of Contents (TOC) for the item named
790 /// \a i_id, assigning \a o_data if the item is found and is a string.  It is
791 /// the caller's responsibility to copy the string from the \a i_image memory
792 /// space if necessary.
793 ///
794 /// \retval 0 Success
795 ///
796 /// \retval non-0 See \ref sbe_xip_image_errors
797 int
798 sbe_xip_get_string(void *i_image, const char* i_id, char** o_data);
799 
800 
801 /// Directly read 64-bit data from the image based on a PORE address
802 ///
803 /// \param[in] i_image A pointer to an SBE-XIP image in host memory.  The
804 /// image is assumed to be consistent with the information contained in the
805 /// header regarding the presence of and sizes of all sections.
806 ///
807 /// \param[in] i_poreAddress A relocatable PORE address contained in the
808 /// image, presumably of an 8-byte data area.  The \a i_poreAddress is
809 /// required to be 8-byte aligned, otherwise the SBE_XIP_ALIGNMENT_ERROR code
810 /// is returned.
811 ///
812 /// \param[out] o_data The 64 bit data in host format that was found at \a
813 /// i_poreAddress.
814 ///
815 /// This API is provided for applications that need to manipulate SBE-XIP
816 /// images in terms of their relocatable PORE addresses.  The API checks that
817 /// the \a i_poreAddress is properly aligned and contained in the image, then
818 /// reads the contents of \a i_poreAddress into \a o_data, performing
819 /// image-to-host endianness conversion if required.
820 ///
821 /// \retval 0 Success
822 ///
823 /// \retval non-0 See \ref sbe_xip_image_errors
824 int
825 sbe_xip_read_uint64(const void *i_image,
826                     const uint64_t i_poreAddress,
827                     uint64_t* o_data);
828 
829 
830 /// Set scalar data in an SBE-XIP image
831 ///
832 /// \param[in,out] io_image A pointer to an SBE-XIP image in host memory.
833 /// The image is assumed to be consistent with the information contained in
834 /// the header regarding the presence of and sizes of all sections.  The image
835 /// is also required to have been normalized.
836 ///
837 /// \param[in] i_id A pointer to a 0-terminated ASCII string naming the item
838 /// to be modified.
839 ///
840 /// \param[in] i_data The new scalar data.
841 ///
842 /// This API searches the SBE-XIP Table of Contents (TOC) for the item named
843 /// by \a i_id, updating the image from \a i_data if the item is found, has
844 /// a scalar type and can be modified.  For this API the scalar types include
845 /// 8- 32- and 64-bit integers.  Although PORE addresses are considered a
846 /// scalar type for sbe_xip_get_scalar(), PORE addresses can not be modified
847 /// by this API.  The caller is responsible for ensuring that the \a i_data is
848 /// of the correct size for the underlying data element in the image.
849 ///
850 /// \retval 0 Success
851 ///
852 /// \retval non-0 See \ref sbe_xip_image_errors
853 int
854 sbe_xip_set_scalar(void* io_image, const char* i_id, const uint64_t i_data);
855 
856 
857 /// Set an integral element in a vector held in an SBE-XIP image
858 ///
859 /// \param[in] i_image A pointer to an SBE-XIP image in host memory.  The
860 /// image is assumed to be consistent with the information contained in the
861 /// header regarding the presence of and sizes of all sections.  The image is
862 /// also required to have been normalized.
863 ///
864 /// \param[in] i_id A pointer to a 0-terminated ASCII string naming the item
865 /// to be updated.
866 ///
867 /// \param[in] i_index  The index of the vector element to update.
868 ///
869 /// \param[out] i_data The new vector element.
870 ///
871 /// This API searches the SBE-XIP Table of Contents (TOC) for the \a i_index
872 /// element of the item named \a i_id, update the image from \a i_data if the
873 /// item is found, is a vector of an integral type, and the \a i_index is in
874 /// bounds.  The caller is responsible for ensuring that the \a i_data is of
875 /// the correct size for the underlying data element in the image.
876 ///
877 /// \retval 0 Success
878 ///
879 /// \retval non-0 See \ref sbe_xip_image_errors
880 int
881 sbe_xip_set_element(void *i_image,
882                     const char* i_id,
883                     const uint32_t i_index,
884                     const uint64_t i_data);
885 
886 
887 /// Set string data in an SBE-XIP image
888 ///
889 /// \param[in,out] io_image A pointer to an SBE-XIP image in host memory.  The
890 /// image is assumed to be consistent with the information contained in the
891 /// header regarding the presence of and sizes of all sections.  The image is
892 /// also required to have been normalized.
893 ///
894 /// \param[in] i_id A pointer to a 0-terminated ASCII string naming the item
895 /// to be modified.
896 ///
897 /// \param[in] i_data A pointer to the new string data.
898 ///
899 /// This API searches the SBE-XIP Table of Contents (TOC) for the item named
900 /// \a i_id, which must be a string variable.  If found, then the string data
901 /// in the image is overwritten with \a i_data.  Strings are held 0-terminated
902 /// in the image, and the SBE-XIP format does not maintain a record of the
903 /// amount of memory allocated for an individual string.  If a string is
904 /// overwritten by a shorter string then the 'excess' storage is effectively
905 /// lost.  If the length of \a i_data is longer that the current strlen() of
906 /// the string data then \a i_data is silently truncated to the first
907 /// strlen(old_string) characters.
908 ///
909 /// \retval 0 Success
910 ///
911 /// \retval non-0 See \ref sbe_xip_image_errors
912 int
913 sbe_xip_set_string(void *io_image, const char* i_id, const char* i_data);
914 
915 
916 /// Directly write 64-bit data into the image based on a PORE address
917 ///
918 /// \param[in, out] io_image A pointer to an SBE-XIP image in host memory.  The
919 /// image is assumed to be consistent with the information contained in the
920 /// header regarding the presence of and sizes of all sections.
921 ///
922 /// \param[in] i_poreAddress A relocatable PORE address contained in the
923 /// image, presumably of an 8-byte data area.  The \a i_poreAddress is
924 /// required to be 8-byte aligned, otherwise the SBE_XIP_ALIGNMENT_ERROR code
925 /// is returned.
926 ///
927 /// \param[in] i_data The 64 bit data in host format to be written to \a
928 /// i_poreAddress.
929 ///
930 /// This API is provided for applications that need to manipulate SBE-XIP
931 /// images in terms of their relocatable PORE addresses.  The API checks that
932 /// the \a i_poreAddress is properly aligned and contained in the image, then
933 /// updates the contents of \a i_poreAddress with \a i_data, performing
934 /// host-to-image endianness conversion if required.
935 ///
936 /// \retval 0 Success
937 ///
938 /// \retval non-0 See \ref sbe_xip_image_errors
939 int
940 sbe_xip_write_uint64(void *io_image,
941                      const uint64_t i_poreAddress,
942                      const uint64_t i_data);
943 
944 
945 /// Map over an SBE-XIP image Table of Contents
946 ///
947 /// \param[in,out] io_image A pointer to an SBE-XIP image in host memory.  The
948 /// image is assumed to be consistent with the information contained in the
949 /// header regarding the presence of and sizes of all sections.  The image is
950 /// also required to have been normalized.
951 ///
952 /// \param[in] i_fn A pointer to a function to call on each TOC entry.  The
953 /// function has the prototype:
954 ///
955 /// \code
956 /// int (*i_fn)(void* io_image,
957 ///             const SbeXipItem* i_item,
958 ///             void* io_arg)
959 /// \endcode
960 ///
961 /// \param[in,out] io_arg The private argument of \a i_fn.
962 ///
963 /// This API iterates over each entry of the TOC, calling \a i_fn with
964 /// pointers to the image, an SbeXipItem* pointer, and a private argument. The
965 /// iteration terminates either when all TOC entries have been mapped, or \a
966 /// i_fn returns a non-zero code.
967 ///
968 /// \retval 0 Success; All TOC entries were mapped, including the case that
969 /// the .toc section is empty.
970 ///
971 /// \retval non-0 May be either one of the SBE-XIP image error codes (see \ref
972 /// sbe_xip_image_errors), or a non-zero code from \a i_fn. Since the standard
973 /// SBE_XIP return codes are > 0, application-defined codes should be < 0.
974 int
975 sbe_xip_map_toc(void* io_image,
976                  int (*i_fn)(void* io_image,
977                              const SbeXipItem* i_item,
978                              void* io_arg),
979                  void* io_arg);
980 
981 
982 /// Find an SBE-XIP TOC entry
983 ///
984 /// \param[in] i_image A pointer to an SBE-XIP image in host memory.  The
985 /// image is assumed to be consistent with the information contained in the
986 /// header regarding the presence of and sizes of all sections.  The image is
987 /// also required to have been normalized.
988 ///
989 /// \param[in] i_id A 0-byte terminated ASCII string naming the item to be
990 /// searched for.
991 ///
992 /// \param[out] o_item If the search is successful, then the object
993 /// pointed to by \a o_item is filled in with the decoded form of the
994 /// TOC entry for \a i_id.  If the API returns a non-0 error code then the
995 /// final state of the storage at \a o_item is undefined.  This parameter may
996 /// be suppied as 0, in which case sbe_xip_find() serves as a simple predicate
997 /// on whether an item is indexded in the TOC.
998 ///
999 /// This API searches the TOC of a normalized SBE-XIP image for the item named
1000 /// \a i_id, and if found, fills in the structure pointed to by \a
1001 /// o_item with a decoded form of the TOC entry.  If the item is not found,
1002 /// the following two return codes may be considered non-error codes:
1003 ///
1004 /// - SBE_XIP_ITEM_NOT_FOUND : No TOC record for \a i_id was found.
1005 ///
1006 /// - SBE_XIP_DATA_NOT_PRESENT : The item appears in the TOC, however the
1007 /// section containing the data is no longer present in the image.
1008 ///
1009 /// If the TOC section has been deleted from the image, then the search is
1010 /// restricted to the abbreviated TOC that indexes data in the .fixed section.
1011 /// In this case the \a o_item structure is marked with a 1 in the \a
1012 /// iv_partial field since the abbreviated TOC can not populate the entire
1013 /// SbeXipItem structure.
1014 ///
1015 /// \note This API should typically only be used as a predicate, not as a way
1016 /// to access the image via the returned SbeXipItem structure. To obtain data
1017 /// from the image or update data in the image use the sbe_xip_get_*() and
1018 /// sbe_xip_set_*() APIs respectively.
1019 ///
1020 /// \retval 0 Success
1021 ///
1022 /// \retval non-0 See \ref sbe_xip_image_errors
1023 int
1024 sbe_xip_find(void* i_image,
1025              const char* i_id,
1026              SbeXipItem* o_item);
1027 
1028 
1029 /// Map over an SBE-XIP image .halt section
1030 ///
1031 /// \param[in,out] io_image A pointer to an SBE-XIP image in host memory.  The
1032 /// image is assumed to be consistent with the information contained in the
1033 /// header regarding the presence of and sizes of all sections.
1034 ///
1035 /// \param[in] i_fn A pointer to a function to call on each entry in .halt.
1036 /// The function has the prototype:
1037 ///
1038 /// \code
1039 /// int (*i_fn)(void* io_image,
1040 ///             const uint64_t i_poreAddress,
1041 ///             const char* i_rcString,
1042 ///             void* io_arg)
1043 ///
1044 /// \endcode
1045 ///
1046 /// \param[in,out] io_arg The private argument of \a i_fn.
1047 ///
1048 /// This API iterates over each entry of the .halt section, calling \a i_fn
1049 /// with each HALT address, the string form of the return code associated with
1050 /// that HALT address, and a private argument. The iteration terminates either
1051 /// when all .halt entries have been mapped, or \a i_fn returns a non-zero
1052 /// code.  The \a i_poreAddddress passed to \a i_fn is the full 48-bit
1053 /// relocatable PORE address.
1054 ///
1055 /// \retval 0 Success, including the case that the image has no .halt section.
1056 ///
1057 /// \retval non-0 May be either one of the SBE-XIP image error codes (see \ref
1058 /// sbe_xip_image_errors), or any non-zero code from \a i_fn.  Since the
1059 /// standard SBE_XIP return codes are \> 0, application-defined codes should
1060 /// be \< 0.
1061 int
1062 sbe_xip_map_halt(void* io_image,
1063                  int (*i_fn)(void* io_image,
1064                              const uint64_t i_poreAddress,
1065                              const char* i_rcString,
1066                              void* io_arg),
1067                  void* io_arg);
1068 
1069 
1070 /// Get the string from of a HALT code from an SBE-XIP image .halt section
1071 ///
1072 /// \param[in,out] io_image A pointer to an SBE-XIP image in host memory.  The
1073 /// image is assumed to be consistent with the information contained in the
1074 /// header regarding the presence of and sizes of all sections.
1075 ///
1076 /// \param[in] i_poreAddress This is the 48-bit address found in the PC when
1077 /// the PORE halts.  This address is actually 4 bytes beyond the actual HALT
1078 /// instruction, however for simplicity this is the address used to index the
1079 /// HALT.
1080 ///
1081 /// \param[out] o_rcString The caller provides the address of a string-pointer
1082 /// variable which is updated with a pointer to the string form of the halt
1083 /// code associated with \a i_poreAddress (assuming a successful completion).
1084 ///
1085 /// \retval 0 Success
1086 ///
1087 /// \revtal SBE_XIP_ITEM_NOT_FOUND The \a i_poreAddress is not associated
1088 /// with a halt code in .halt.
1089 ///
1090 /// \revtal Other See \ref sbe_xip_image_errors
1091 int
1092 sbe_xip_get_halt(void* io_image,
1093                  const uint64_t i_poreAddress,
1094                  const char** o_rcString);
1095 
1096 
1097 /// Delete a section from an SBE-XIP image in host memory
1098 ///
1099 /// \param[in,out] io_image A pointer to an SBE-XIP image in host memory.  The
1100 /// image is assumed to be consistent with the information contained in the
1101 /// header regarding the presence of and sizes of all sections. The image is
1102 /// also required to have been normalized.
1103 ///
1104 /// \param[in] i_sectionId Identifies the section to be deleted.  See \ref
1105 /// sbe_xip_sections.
1106 ///
1107 /// This API effectively deletes a section from an SBE-XIP image held in host
1108 /// memory.  Unless the requested section \a i_section is already empty, only
1109 /// the final (highest address offset) section of the image may be deleted.
1110 /// Deleting the final section of the image means that the section size is set
1111 /// to 0, and the size of the image recorded in the header is reduced by the
1112 /// section size.  Any alignment padding of the now-last section is also
1113 /// removed.
1114 ///
1115 /// \note This API does not check for or warn if other sections in the image
1116 /// reference the deleted section.
1117 ///
1118 /// \retval 0 Success
1119 ///
1120 /// \retval non-0 See \ref sbe_xip_image_errors
1121 int
1122 sbe_xip_delete_section(void* io_image, const int i_sectionId);
1123 
1124 
1125 #ifndef PPC_HYP
1126 
1127 /// Duplicate a section from an SBE-XIP image in host memory
1128 ///
1129 /// \param[in,out] i_image A pointer to an SBE-XIP image in host memory.  The
1130 /// image is assumed to be consistent with the information contained in the
1131 /// header regarding the presence of and sizes of all sections.
1132 ///
1133 /// \param[in] i_sectionId Identifies the section to be duplicated.  See \ref
1134 /// sbe_xip_sections.
1135 ///
1136 /// \param[out] o_duplicate At exit, points to the newly allocated and
1137 /// initialized duplicate of the given section. The caller is responsible for
1138 /// free()-ing this memory when no longer required.
1139 ///
1140 /// \param[out] o_size At exit, contains the size (in bytes) of the duplicated
1141 /// section.
1142 ///
1143 /// This API creates a bytewise duplicate of a non-empty section into newly
1144 /// malloc()-ed memory. At exit \a o_duplicate points to the duplicate, and \a
1145 /// o_size is set the the size of the duplicated section. The caller is
1146 /// responsible for free()-ing the memory when no longer required.  The
1147 /// pointer at \a o_duplicate is set to NULL (0) and the \a o_size is set to 0
1148 /// in the event of any failure.
1149 ///
1150 /// \retval 0 Success
1151 ///
1152 /// \retval non-0 See \ref sbe_xip_image_errors
1153 int
1154 sbe_xip_duplicate_section(const void* i_image,
1155                           const int i_sectionId,
1156                           void** o_duplicate,
1157                           uint32_t* o_size);
1158 
1159 #endif // PPC_HYP
1160 
1161 
1162 /// Append binary data to an SBE-XIP image held in host memory
1163 ///
1164 /// \param[in,out] io_image A pointer to an SBE-XIP image in host memory.  The
1165 /// image is assumed to be consistent with the information contained in the
1166 /// header regarding the presence of and sizes of all sections. The image is
1167 /// also required to have been normalized.
1168 ///
1169 /// \param[in] i_sectionId Identifies the section to contain the new data.
1170 ///
1171 /// \param[in] i_data A pointer to the data to be appended to the image.  If
1172 /// this pointer is NULL (0), then the effect is as if \a i_data were a
1173 /// pointer to an \a i_size array of 0 bytes.
1174 ///
1175 /// \param[in] i_size The size of the data to be appended in bytes.  If \a
1176 /// i_data is 0, then this is the number of bytes to clear.
1177 ///
1178 /// \param[in] i_allocation The size of the memory region containing the
1179 /// image, measured from the first byte of the image.  The call will fail if
1180 /// appending the new data plus any alignment padding would overflow the
1181 /// allocated memory.
1182 ///
1183 /// \param[out] o_sectionOffset If non-0 at entry, then the API updates the
1184 /// location pointed to by \a o_sectionOffset with the offset of the first
1185 /// byte of the appended data within the indicated section. This return value
1186 /// is invalid in the event of a non-0 return code.
1187 ///
1188 /// This API copies data from \a i_data to the end of the indicated \a
1189 /// i_section.  The section \a i_section must either be empty, or must be the
1190 /// final (highest address) section in the image.  If the section is initially
1191 /// empty and \a i_size is non-0 then the section is created at the end of the
1192 /// image.  The size of \a i_section and the size of the image are always
1193 /// adjusted to reflect the newly added data.  This is a simple binary copy
1194 /// without any interpretation (e.g., endian-translation) of the copied data.
1195 /// The caller is responsible for insuring that the host memory area
1196 /// containing the SBE-XIP image is large enough to hold the newly appended
1197 /// data without causing addressing errors or buffer overrun errors.
1198 ///
1199 /// The final parameter \a o_sectionOffset is optional, and may be passed as
1200 /// NULL (0) if the application does not require the information.  This return
1201 /// value is provided to simplify typical use cases of this API:
1202 ///
1203 /// - A scan program is appended to the image, or a run-time data area is
1204 /// allocated and cleared at the end of the image.
1205 ///
1206 /// - Pointer variables in the image are updated with PORE addresses obtained
1207 /// via sbe_xip_section2pore(), or
1208 /// other procedure code initializes a newly allocated and cleared data area
1209 /// via host addresses obtained from sbe_xip_section2host().
1210 ///
1211 /// Regarding alignment, note that the SBE-XIP format requires that sections
1212 /// maintain an initial alignment that varies by section, and the API will
1213 /// enforce these alignment constraints for all sections created by the API.
1214 /// All alignment is relative to the first byte of the image (\a io_image) -
1215 /// \e not to the current in-memory address of the image. By specification
1216 /// SBE-XIP images must be loaded at a 4K alignment in order for PORE hardware
1217 /// relocation to work, however the APIs don't require this 4K alignment for
1218 /// in-memory manipulation of images.  Images to be executed on PoreVe will
1219 /// normally require at least 8-byte final aligment in order to guarantee that
1220 /// the PoreVe can execute an 8-byte fetch or load/store of the final
1221 /// doubleword.
1222 ///
1223 /// \note If the TOC section is modified then the image is marked as having an
1224 /// unsorted TOC.
1225 ///
1226 /// \note If the call fails for any reason (other than a bug in the API
1227 /// itself) then the \a io_image data is returned unmodified.
1228 ///
1229 /// \retval 0 Success
1230 ///
1231 /// \retval non-0 See \ref sbe_xip_image_errors
1232 int
1233 sbe_xip_append(void* io_image,
1234                const int i_sectionId,
1235                const void* i_data,
1236                const uint32_t i_size,
1237                const uint32_t i_allocation,
1238                uint32_t* o_sectionOffset);
1239 
1240 
1241 /// Convert an SBE-XIP section offset to a relocatable PORE address
1242 ///
1243 /// \param[in] i_image A pointer to an SBE-XIP image in host memory
1244 ///
1245 /// \param[in] i_sectionId A valid SBE-XIP section identifier; The section
1246 /// must be non-empty.
1247 ///
1248 /// \param[in] i_offset An offset (in bytes) within the section.  At least one
1249 /// byte at \a i_offset must be currently allocated in the section.
1250 ///
1251 /// \param[in] o_poreAddress The equivalent relocatable PORE address is
1252 /// returned via this pointer. Since valid PORE addresses are always either
1253 /// 4-byte (code) or 8-byte (data) aligned, this API checks the aligment of
1254 /// the translated address and returns SBE_XIP_ALIGNMENT_ERROR if the PORE
1255 /// address is not at least 4-byte aligned.  Note that the translated address
1256 /// is still returned even if incorrectly aligned.
1257 ///
1258 /// This API is typically used to translate section offsets returned from
1259 /// sbe_xip_append() into relocatable PORE addresses.
1260 ///
1261 /// \retval 0 Success
1262 ///
1263 /// \retval non-0 See \ref sbe_xip_image_errors
1264 int
1265 sbe_xip_section2pore(const void* i_image,
1266                      const int i_sectionId,
1267                      const uint32_t i_offset,
1268                      uint64_t* o_poreAddress);
1269 
1270 
1271 /// Convert an SBE-XIP relocatable PORE address to a host memory address
1272 ///
1273 /// \param[in] i_image A pointer to an SBE-XIP image in host memory.
1274 ///
1275 /// \param[in] i_poreAddress A relocatable PORE address putatively addressing
1276 /// relocatable memory contained in the image.
1277 ///
1278 /// \param[out] o_hostAddress The API updates the location pointed to by \a
1279 /// o_hostAddress with the host address of the memory addressed by \a
1280 /// i_poreAddress.  In the event of an error (non-0 return code) the final
1281 /// content of \a o_hostAddress is undefined.
1282 ///
1283 /// This API is typically used to translate relocatable PORE addresses stored
1284 /// in the SBE-XIP image into the equivalent host address of the in-memory
1285 /// image, allowing host-code to manipulate arbitrary data structures in the
1286 /// image. If the \a i_poreAddress does not refer to memory within the image
1287 /// (as determined by the link address and image size) then the
1288 /// SBE_XIP_INVALID_ARGUMENT error code is returned.
1289 ///
1290 /// \retval 0 Success
1291 ///
1292 /// \retval non-0 See \ref sbe_xip_image_errors
1293 int
1294 sbe_xip_pore2host(const void* i_image,
1295                   const uint64_t i_poreAddress,
1296                   void** o_hostAddress);
1297 
1298 
1299 /// Convert an SBE-XIP relocatable PORE address to section Id and offset
1300 ///
1301 /// \param[in] i_image A pointer to an SBE-XIP image in host memory.
1302 ///
1303 /// \param[in] i_poreAddress A relocatable PORE address putatively addressing
1304 /// relocatable memory contained in the image.
1305 ///
1306 /// \param[out] o_section The API updates the location pointed to by \a
1307 /// o_section with the section Id of the memory addressed by \a
1308 /// i_poreAddress.  In the event of an error (non-0 return code) the final
1309 /// content of \a o_section is undefined.
1310 ///
1311 /// \param[out] o_offset The API updates the location pointed to by \a
1312 /// o_offset with the byte offset of the memory addressed by \a i_poreAddress
1313 /// within \a o_section.  In the event of an error (non-0 return code) the
1314 /// final content of \a o_offset is undefined.
1315 ///
1316 /// This API is typically used to translate relocatable PORE addresses stored
1317 /// in the SBE-XIP image into the equivalent section + offset form, allowing
1318 /// host-code to manipulate arbitrary data structures in the image. If the \a
1319 /// i_poreAddress does not refer to memory within the image (as determined by
1320 /// the link address and image size) then the SBE_XIP_INVALID_ARGUMENT error
1321 /// code is returned.
1322 ///
1323 /// \retval 0 Success
1324 ///
1325 /// \retval non-0 See \ref sbe_xip_image_errors
1326 int
1327 sbe_xip_pore2section(const void* i_image,
1328                      const uint64_t i_poreAddress,
1329                      int* o_section,
1330                      uint32_t* o_offset);
1331 
1332 
1333 /// Convert an in-memory SBE-XIP host address to a relocatable PORE address
1334 ///
1335 /// \param[in] i_image A pointer to an SBE-XIP image in host memory
1336 ///
1337 /// \param[in] i_hostAddress A host address addressing data within the image.
1338 ///
1339 /// \param[out] o_poreAddress The API updates the location pointed to by \a
1340 /// o_poreAddress with the equivalent relocatable PORE address of the memory
1341 /// addressed by i_hostAddress.  Since valid PORE addresses are always either
1342 /// 4-byte (code) or 8-byte (data) aligned, this API checks the aligment of
1343 /// the translated address and returns SBE_XIP_ALIGNMENT_ERROR if the PORE
1344 /// address is not at least 4-byte aligned.  Note that the translated address
1345 /// is still returned evn if incorrectly aligned.
1346 ///
1347 /// This API is provided as a convenient way to convert host memory addresses
1348 /// for an in-memory SBE-XIP image into PORE addresses correctly relocated for
1349 /// the image, for example to update pointer variables in the image.  If the
1350 /// \a i_hostAddress does not refer to memory within the image (as determined
1351 /// by the image address and image size) then the SBE_XIP_INVALID_ARGUMENT
1352 /// error code is returned.
1353 ///
1354 /// \retval 0 Success
1355 ///
1356 /// \retval non-0 See \ref sbe_xip_image_errors
1357 int
1358 sbe_xip_host2pore(const void* i_image,
1359                   void* i_hostAddress,
1360                   uint64_t* o_poreAddress);
1361 
1362 
1363 /// \defgroup sbe_xip_image_errors Error codes from SBE-XIP image APIs
1364 ///
1365 /// @{
1366 
1367 /// A putative SBE-XIP image does not have the correct magic number, or
1368 /// contains some other major inconsistency.
1369 #define SBE_XIP_IMAGE_ERROR 1
1370 
1371 /// The TOC may be missing, partially present or may have an alignment problem.
1372 #define SBE_XIP_TOC_ERROR 2
1373 
1374 /// A named item was not found in the SBE-XIP TOC, or a putative HALT address
1375 /// is not associated with a halt code in .halt.
1376 #define SBE_XIP_ITEM_NOT_FOUND 3
1377 
1378 /// A named item appears in the SBE-XIP TOC, but the data is not present in
1379 /// the image.  This error can occur if sections have been deleted from the
1380 /// image.
1381 #define SBE_XIP_DATA_NOT_PRESENT 4
1382 
1383 /// A named item appears in the SBE-XIP TOC, but the data can not be
1384 /// modified. This error will occur if an attempt is made to modify an
1385 /// address-only entry.
1386 #define SBE_XIP_CANT_MODIFY 5
1387 
1388 /// A direct or implied argument is invalid, e.g. an illegal data type or
1389 /// section identifier, or an address not contained within the image.
1390 #define SBE_XIP_INVALID_ARGUMENT 6
1391 
1392 /// A data type mismatch or an illegal type was specified or implied for an
1393 /// operation.
1394 #define SBE_XIP_TYPE_ERROR 7
1395 
1396 /// A bug in an SBE-XIP image API
1397 #define SBE_XIP_BUG 8
1398 
1399 /// The image must first be normalized with sbe_xip_normalize().
1400 #define SBE_XIP_NOT_NORMALIZED 9
1401 
1402 /// Attempt to delete a non-empty section that is not the final section of the
1403 /// image, or an attempt to append data to a non-empty section that is not the
1404 /// final section of the image, or an attempt to operate on an empty section
1405 /// for those APIs that prohibit this.
1406 #define SBE_XIP_SECTION_ERROR 10
1407 
1408 /// An address translation API returned a PORE address that was not at least
1409 /// 4-byte aligned, or alignment violations were observed by
1410 /// sbe_xip_validate() or sbe_xip_append().
1411 #define SBE_XIP_ALIGNMENT_ERROR 11
1412 
1413 /// An API that performs dynamic memory allocation was unable to allocate
1414 /// memory.
1415 #define SBE_XIP_NO_MEMORY 12
1416 
1417 /// Attempt to get or set a vector element with an index that is outside of
1418 /// the declared bounds of the vector.
1419 #define SBE_XIP_BOUNDS_ERROR 13
1420 
1421 /// Attempt to grow the image past its defined memory allocation
1422 #define SBE_XIP_WOULD_OVERFLOW 14
1423 
1424 /// Error associated with the disassembler occurred.
1425 #define SBE_XIP_DISASSEMBLER_ERROR 15
1426 
1427 /// hash collision creating the .fixed_toc section
1428 #define SBE_XIP_HASH_COLLISION 16
1429 
1430 /// Applications can expand this macro to declare an array of string forms of
1431 /// the error codes if desired.
1432 #define SBE_XIP_ERROR_STRINGS(var)              \
1433     const char* var[] = {                       \
1434         "Success",                              \
1435         "SBE_XIP_IMAGE_ERROR",                  \
1436         "SBE_XIP_TOC_ERROR",                    \
1437         "SBE_XIP_ITEM_NOT_FOUND",               \
1438         "SBE_XIP_DATA_NOT_PRESENT",             \
1439         "SBE_XIP_CANT_MODIFY",                  \
1440         "SBE_XIP_INVALID_ARGUMENT",             \
1441         "SBE_XIP_TYPE_ERROR",                   \
1442         "SBE_XIP_BUG",                          \
1443         "SBE_XIP_NOT_NORMALIZED",               \
1444         "SBE_XIP_SECTION_ERROR",                \
1445         "SBE_XIP_ALIGNMENT_ERROR",              \
1446         "SBE_XIP_NO_MEMORY",                    \
1447         "SBE_XIP_BOUNDS_ERROR",                 \
1448         "SBE_XIP_WOULD_OVERFLOW",               \
1449         "SBE_XIP_DISASSEMBLER_ERROR",           \
1450         "SBE_XIP_HASH_COLLISION",               \
1451     }
1452 
1453 /// Applications can use this macro to safely index the array of error
1454 /// strings.
1455 #define SBE_XIP_ERROR_STRING(var, n)                                   \
1456     ((((n) < 0) || ((n) > (int)(sizeof(var) / sizeof(char*)))) ?        \
1457      "Bug : Invalid SBE-XIP error code" : var[n])
1458 
1459 /// @}
1460 
1461 /// Disassembler error codes.
1462 #define DIS_IMAGE_ERROR                   1
1463 #define DIS_MEMORY_ERROR                  2
1464 #define DIS_DISASM_ERROR                  3
1465 #define DIS_RING_NAME_ADDR_MATCH_SUCCESS  4
1466 #define DIS_RING_NAME_ADDR_MATCH_FAILURE  5
1467 #define DIS_TOO_MANY_DISASM_WARNINGS      6
1468 #define DIS_DISASM_TROUBLES               7
1469 
1470 #define DIS_ERROR_STRINGS(var)              \
1471     const char* var[] = {                   \
1472         "Success",                          \
1473         "DIS_IMAGE_ERROR",                  \
1474         "DIS_MEMORY_ERROR",                 \
1475         "DIS_DISASM_ERROR",                 \
1476         "DIS_RING_NAME_ADDR_MATCH_SUCCESS", \
1477         "DIS_RING_NAME_ADDR_MATCH_FAILURE", \
1478         "DIS_TOO_MANY_DISASM_WARNINGS",     \
1479         "DIS_DISASM_TROUBLES",              \
1480     }
1481 
1482 #define DIS_ERROR_STRING(var, n)                                   \
1483     ((((n) < 0) || ((n) > (int)(sizeof(var) / sizeof(char*)))) ?        \
1484      "Bug : Invalid DIS error code" : var[n])
1485 
1486 #if 0
1487 { /* So __cplusplus doesn't mess w/auto-indent */
1488 #endif
1489 #ifdef __cplusplus
1490 }
1491 #endif
1492 
1493 #endif  // __ASSEMBLER__
1494 
1495 
1496 ////////////////////////////////////////////////////////////////////////////
1497 // Assembler Definitions
1498 ////////////////////////////////////////////////////////////////////////////
1499 
1500 #ifdef __ASSEMBLER__
1501 
1502 /// Create an XIP TOC entry
1503 ///
1504 /// \param[in] index The string form of the \a index symbol is created and
1505 /// linked from the TOC entry to allow external search procedures to locate
1506 /// the \a address.
1507 ///
1508 /// \param[in] type One of the SBE_XIP_* type constants; See \ref
1509 /// sbe_xip_toc_types.
1510 ///
1511 /// \param[in] address The address of the idexed code or data; This wlll
1512 /// typically be a symbol.
1513 ///
1514 /// \param[in] elements <Optional> For vector types, number of elements in the
1515 /// vector, which is limited to an 8-bit unsigned integer.  This parameter
1516 /// defaults to 1 which indicates a scalar type. Declaring a vector with 0
1517 /// elements disables bounds checking on vector accesses, and can be used if
1518 /// very large or indeterminate sized vectors are required. The TOC format
1519 /// does not support vectors of strings or addresses.
1520 ///
1521 /// The \c .xip_toc macro creates a XIP Table of Contents (TOC) structure in
1522 /// the \c .toc section, as specified by the parameters.  This macro is
1523 /// typically not used directly in assembly code.  Instead programmers should
1524 /// use .xip_quad, .xip_quada, .xip_quadia, .xip_address, .xip_string or
1525 /// .xip_cvs_revision.
1526 
1527         .macro  .xip_toc, index:req, type:req, address:req, elements=1
1528 
1529 	.if	(((\type) < 1) || ((\type) > SBE_XIP_MAX_TYPE_INDEX))
1530 	.error	".xip_toc : Illegal type index"
1531 	.endif
1532 
1533         // First push into the .strings section to lay down the
1534         // string form of the index name under a local label.
1535 
1536         .pushsection .strings
1537 7667862:
1538         .asciz  "\index"
1539         .popsection
1540 
1541         // Now the 12-byte TOC entry is created.  Push into the .toc section
1542 	// and lay down the first 4 bytes which are always a pointer to the
1543 	// string just declared.  The next 4 bytes are the address of the data
1544 	// (or the address itself in the case of address types). The final 4
1545 	// bytes are the type, section (always 0 prior to normalization),
1546 	// number of elements, and a padding byte.
1547 
1548 	.pushsection .toc
1549 
1550 	.long	7667862b, (\address)
1551 	.byte	(\type), 0, (\elements), 0
1552 
1553 	.popsection
1554 
1555 	.endm
1556 
1557 
1558 /// Allocate and initialize 64-bit global scalar or vector data and create the
1559 /// TOC entry.
1560 ///
1561 /// \param[in] symbol The name of the scalar or vector; this name is also used
1562 /// as the TOC index of the data.
1563 ///
1564 /// \param[in] init The initial value of (each element of) the data.
1565 /// This is a 64-bit integer; To allocate address pointers use .xip_quada.
1566 ///
1567 /// \param[in] elements The number of 64-bit elements in the data structure,
1568 /// defaulting to 1, with a maximum value of 255.
1569 ///
1570 /// \param[in] section The section where the data will be allocated,
1571 /// default depends on the memory space
1572 
1573 	.macro	.xip_quad, symbol:req, init:req, elements=1, section
1574 
1575         ..xip_quad_helper .quad, \symbol, (\init), (\elements), \section
1576 
1577 	.endm
1578 
1579 
1580 /// Allocate and initialize 64-bit global scalar or vector data containing a
1581 /// relocatable address in and create the TOC entry.
1582 ///
1583 /// \param[in] symbol The name of the scalar or vector; this name is also used
1584 /// as the TOC index of the data.
1585 ///
1586 /// \param[in] init The initial value of (each element of) the data.  This
1587 /// will typically be a symbolic address. If the intention is to define an
1588 /// address that will always be filled in later by image manipulation tools,
1589 /// then use the .xip_quad macro with a 0 initial value.
1590 ///
1591 /// \param[in] elements The number of 64-bit elements in the data structure,
1592 /// defaulting to 1, with a maximum value of 255.
1593 ///
1594 /// \param[in] section The section where the data will be allocated,
1595 /// default depends on the memory space
1596 
1597 	.macro	.xip_quada, symbol:req, offset:req, elements=1, section
1598 
1599 	..xip_quad_helper .quada, \symbol, (\offset), (\elements), \section
1600 
1601 	.endm
1602 
1603 
1604 /// Helper for .xip_quad and .xip_quada
1605 
1606         .macro	..xip_quad_helper, directive, symbol, init, elements, section
1607 
1608 	.if	(((\elements) < 1) || ((\elements) > 255))
1609 	.error	"The number of vector elements must be in the range 1..255"
1610 	.endif
1611 
1612 	..xip_pushsection \section
1613 	.balign 8
1614 
1615 	.global	\symbol
1616 \symbol\():
1617 	.rept	(\elements)
1618         \directive (\init)
1619 	.endr
1620 
1621 	.popsection
1622 
1623 	.xip_toc \symbol, SBE_XIP_UINT64, \symbol, (\elements)
1624 
1625 	.endm
1626 
1627 
1628 /// Allocate and initialize 64-bit global scalar or vector data containing
1629 /// full 64-bit addresses and create a TOC entry
1630 ///
1631 /// \param[in] symbol The name of the scalar or vector; this name is also used
1632 /// as the TOC index of the data.
1633 ///
1634 /// \param[in] space A valid PORE memory space descriptor
1635 ///
1636 /// \param[in] offset A 32-bit relocatable offset
1637 ///
1638 /// \param[in] elements The number of 64-bit elements in the data structure,
1639 /// defaulting to 1, with a maximum value of 255.
1640 ///
1641 /// \param[in] section The section where the data will be allocated,
1642 /// default depends on the memory space
1643 
1644          .macro	.xip_quadia, symbol:req, space:req, offset:req, \
1645 		 elements=1, section
1646 
1647 	.if	(((\elements) < 1) || ((\elements) > 255))
1648 	.error	"The number of vector elements must be in the range 1..255"
1649 	.endif
1650 
1651 	..xip_pushsection \section
1652 	.balign	8
1653 
1654 	.global	\symbol
1655 \symbol\():
1656 	.rept	(\elements)
1657 	.quadia	(\space), (\offset)
1658 	.endr
1659 
1660 	.popsection
1661 
1662 	.xip_toc \symbol, SBE_XIP_UINT64, \symbol, (\elements)
1663 
1664 	.endm
1665 
1666 /// Default push into .ipl_data unless in an OCI space, then .data
1667 
1668 	.macro	..xip_pushsection, section
1669 
1670 	.ifnb	\section
1671 	.pushsection \section
1672 	.else
1673 	.if	(_PGAS_DEFAULT_SPACE == PORE_SPACE_OCI)
1674 	.pushsection .data
1675 	.else
1676 	.pushsection .ipl_data
1677 	.endif
1678 	.endif
1679 
1680 	.balign	8
1681 
1682 	.endm
1683 
1684 /// Allocate and initialize a string in .strings
1685 ///
1686 /// \param[in] index The string will be stored in the TOC using this index
1687 /// symbol.
1688 ///
1689 /// \param[in] string The string to be allocated in .strings. String space is
1690 /// fixed once allocated.  Strings designed to be overwritten by external tools
1691 /// should be allocated to be as long as eventually needed (e.g., by a string
1692 /// of blanks.)
1693 
1694 	.macro	.xip_string, index:req, string:req
1695 
1696 	.pushsection .strings
1697 7874647:
1698 	.asciz	"\string"
1699 	.popsection
1700 
1701 	.xip_toc \index, SBE_XIP_STRING, 7874647b
1702 
1703 	.endm
1704 
1705 
1706 /// Allocate and initialize a CVS Revison string in .strings
1707 ///
1708 /// \param[in] index The string will be stored in the TOC using this index
1709 /// symbol.
1710 ///
1711 /// \param[in] string A CVS revision string to be allocated in .strings.  CVS
1712 /// revision strings are formatted by stripping out and only storing the
1713 /// actual revision number :
1714 ///
1715 /// \code
1716 ///     "$Revision <n>.<m> $" -> "<n>.<m>"
1717 /// \endcode
1718 
1719 
1720 	.macro	.xip_cvs_revision, index:req, string:req
1721 
1722 	.pushsection .strings
1723 7874647:
1724 	..cvs_revision_string "\string"
1725 	.popsection
1726 
1727 	.xip_toc \index, SBE_XIP_STRING, 7874647b
1728 
1729 	.endm
1730 
1731 
1732 /// Shorthand to create a TOC entry for an address
1733 ///
1734 /// \param[in] index The symbol will be indexed as this name
1735 ///
1736 /// \param[in] symbol <Optional> The symbol to index; by default the same as
1737 /// the index.
1738 
1739 	.macro	.xip_address, index:req, symbol
1740 
1741 	.ifb	\symbol
1742 	.xip_toc \index, SBE_XIP_ADDRESS, \index
1743 	.else
1744 	.xip_toc \index, SBE_XIP_ADDRESS, \symbol
1745 	.endif
1746 
1747 	.endm
1748 
1749 
1750 /// Edit and allocate a CVS revision string
1751 ///
1752 /// CVS revision strings are formatted by stripping out and only storing the
1753 /// actual revision number :
1754 /// \code
1755 ///     "$Revision <n>.<m> $" -> "<n>.<m>"
1756 /// \endcode
1757 
1758 	.macro	..cvs_revision_string, rev:req
1759 	.irpc	c, \rev
1760 	.ifnc	"\c", "$"
1761 	.ifnc	"\c", "R"
1762 	.ifnc	"\c", "e"
1763 	.ifnc	"\c", "v"
1764 	.ifnc	"\c", "i"
1765 	.ifnc	"\c", "s"
1766 	.ifnc	"\c", "i"
1767 	.ifnc	"\c", "o"
1768 	.ifnc	"\c", "n"
1769 	.ifnc	"\c", ":"
1770 	.ifnc	"\c", " "
1771 	.ascii	"\c"
1772 	.endif
1773 	.endif
1774 	.endif
1775 	.endif
1776 	.endif
1777 	.endif
1778 	.endif
1779 	.endif
1780 	.endif
1781 	.endif
1782 	.endif
1783 	.endr
1784 	.byte	0
1785 	.endm
1786 
1787 #endif // __ASSEMBLER__
1788 
1789 #endif  // __SBE_XIP_TOC_H
1790