aboutsummaryrefslogtreecommitdiff
path: root/library/src
diff options
context:
space:
mode:
Diffstat (limited to 'library/src')
-rw-r--r--library/src/mipi_syst_api.c1314
-rw-r--r--library/src/mipi_syst_compiler.c78
-rw-r--r--library/src/mipi_syst_crc32.c313
-rw-r--r--library/src/mipi_syst_init.c204
-rw-r--r--library/src/mipi_syst_inline.c48
-rw-r--r--library/src/mipi_syst_writer.c219
6 files changed, 2176 insertions, 0 deletions
diff --git a/library/src/mipi_syst_api.c b/library/src/mipi_syst_api.c
new file mode 100644
index 0000000..6504d81
--- /dev/null
+++ b/library/src/mipi_syst_api.c
@@ -0,0 +1,1314 @@
+/*
+Copyright (c) 2018, MIPI Alliance, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+* Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+* Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+ * Contributors:
+ * Norbert Schulz (Intel Corporation) - Initial API and implementation
+ */
+
+ /* Internal C-language API implementation */
+
+#include "mipi_syst.h"
+#include "mipi_syst/message.h"
+
+#if defined(MIPI_SYST_UNIT_TEST)
+#define ASSERT_CHECK(x) ASSERT_EQ(x, true)
+#else
+#define ASSERT_CHECK(x)
+#endif
+
+#if MIPI_SYST_CONFORMANCE_LEVEL > 10
+
+#if !defined(MIPI_SYST_SCATTER_WRITE)
+/**
+ * Default writer access is to call global state systh_writer pointer.
+ * Redefine this if you can avoid the function pointer overhead.
+ */
+#define MIPI_SYST_SCATTER_WRITE(syst_handle, scatter_prog, data_ptr) \
+ { \
+ (syst_handle)->systh_header->systh_writer( \
+ (syst_handle), (scatter_prog), (data_ptr));\
+ }
+#endif
+
+/**
+ * predefined write scatter instructions defined in scatter_op table
+ */
+enum syst_scatter_ops {
+#if defined(MIPI_SYST_PCFG_ENABLE_ORIGIN_GUID)
+ SCATTER_OP_GUID,
+#endif
+
+#if defined(MIPI_SYST_PCFG_ENABLE_LOCATION_RECORD)
+ SCATTER_OP_LOC_FMT,
+ SCATTER_OP_LOC_32,
+ SCATTER_OP_LOC_64,
+#endif
+#if defined(MIPI_SYST_PCFG_LENGTH_FIELD)
+ SCATTER_OP_LENGTH,
+#endif
+ SCATTER_OP_PAYLD_VAR,
+ SCATTER_OP_CHECKSUM,
+ SCATTER_OP_CATID_32,
+ SCATTER_OP_CATID_64,
+ SCATTER_OP_CATID_ARGS,
+ SCATTER_OP_CLOCK,
+#if defined(MIPI_SYST_PCFG_ENABLE_TIMESTAMP)
+ SCATTER_OP_TS,
+#endif
+#if defined(MIPI_SYST_PCFG_ENABLE_BUILD_API)
+ SCATTER_OP_VER_ID,
+ SCATTER_OP_VER_TXT,
+#endif
+ SCATTER_OP_END
+};
+
+/**
+ * Scatter instruction that describe the writing of SyS-T message descriptor
+ * members by the scatter write algorithm.
+ */
+static const struct mipi_syst_scatter_prog scatter_ops[] = {
+#if defined(MIPI_SYST_PCFG_ENABLE_ORIGIN_GUID)
+
+ { /* SCATTER_OP_GUID */
+ MIPI_SYST_SCATTER_OP_64BIT,
+ MIPI_SYST_EVDSC_MEMBER_OFF(ed_guid),
+ 2},
+#endif
+
+#if defined(MIPI_SYST_PCFG_ENABLE_LOCATION_RECORD)
+ { /* SCATTER_OP_LOC_FMT */
+ MIPI_SYST_SCATTER_OP_8BIT,
+ MIPI_SYST_EVDSC_MEMBER_OFF(ed_loc.el_format),
+ 1},
+ { /* SCATTER_OP_LOC_32 */
+ MIPI_SYST_SCATTER_OP_32BIT,
+ MIPI_SYST_EVDSC_MEMBER_OFF(ed_loc.el_u),
+ 1},
+ { /* SCATTER_OP_LOC_64 */
+ MIPI_SYST_SCATTER_OP_64BIT,
+ MIPI_SYST_EVDSC_MEMBER_OFF(ed_loc.el_u),
+ 1},
+#endif
+#if defined(MIPI_SYST_PCFG_LENGTH_FIELD)
+ { /* SCATTER_OP_LENGTH */
+ MIPI_SYST_SCATTER_OP_16BIT,
+ MIPI_SYST_EVDSC_MEMBER_OFF(ed_len),
+ 1},
+#endif
+ { /* SCATTER_OP_PAYLD_VAR */
+ MIPI_SYST_SCATTER_OP_BLOB,
+ MIPI_SYST_EVDSC_MEMBER_OFF(ed_pld.data_var),
+ 0}
+ ,
+ { /* SCATTER_OP_PAYLD_CHECKSUM */
+ MIPI_SYST_SCATTER_OP_32BIT,
+ MIPI_SYST_EVDSC_MEMBER_OFF(ed_chk),
+ 1}
+ ,
+ { /* SCATTER_OP_CATID_32 */
+ MIPI_SYST_SCATTER_OP_32BIT,
+ MIPI_SYST_EVDSC_MEMBER_OFF(ed_pld.data_catid.id.sci_32),
+ 1}
+ ,
+ { /* SCATTER_OP_CATID_64 */
+ MIPI_SYST_SCATTER_OP_64BIT,
+ MIPI_SYST_EVDSC_MEMBER_OFF(ed_pld.data_catid.id.sci_64),
+ 1}
+ ,
+ { /* SCATTER_OP_CATID_ARGS */
+ MIPI_SYST_SCATTER_OP_BLOB,
+ MIPI_SYST_EVDSC_MEMBER_OFF(ed_pld.data_catid.param),
+ 0}
+ ,
+ { /* SCATTER_OP_CLOCK */
+ MIPI_SYST_SCATTER_OP_64BIT,
+ MIPI_SYST_EVDSC_MEMBER_OFF(ed_pld.data_clock),
+ 2}
+ ,
+#if defined(MIPI_SYST_PCFG_ENABLE_TIMESTAMP) /* SCATTER_OP_TS */
+ {
+ MIPI_SYST_SCATTER_OP_64BIT,
+ MIPI_SYST_EVDSC_MEMBER_OFF(ed_ts),
+ 1}
+ ,
+#endif /* defined(MIPI_SYST_PCFG_ENABLE_TIMESTAMP) */
+#if defined(MIPI_SYST_PCFG_ENABLE_BUILD_API)
+ { /* SCATTER_OP_VER_ID */
+ MIPI_SYST_SCATTER_OP_64BIT,
+ MIPI_SYST_EVDSC_MEMBER_OFF(ed_pld.data_version.id),
+ 1}
+ ,
+ { /* SCATTER_OP_VER_TXT */
+ MIPI_SYST_SCATTER_OP_BLOB,
+ MIPI_SYST_EVDSC_MEMBER_OFF(ed_pld.data_version.text),
+ 0}
+ ,
+#endif /* defined(MIPI_SYST_PCFG_ENABLE_BUILD_API) */
+
+ { /* SCATTER_OP_END */
+ MIPI_SYST_SCATTER_OP_END,
+ 0,
+ 0}
+};
+
+
+/**
+ * Add optional message components to the message descriptor
+ */
+static
+#if defined(MIPI_SYST_PCFG_ENABLE_INLINE)
+MIPI_SYST_CC_INLINE
+#endif
+void
+insert_optional_msg_components(struct mipi_syst_handle* svh,
+ struct mipi_syst_msglocation* loc,
+ mipi_syst_u16 len,
+ struct mipi_syst_msgdsc *desc,
+ struct mipi_syst_scatter_prog **prog_ptr)
+{
+ struct mipi_syst_scatter_prog *prog = *prog_ptr;
+
+#if defined(MIPI_SYST_PCFG_ENABLE_ORIGIN_GUID)
+ /* origin GUID ? */
+ if (0 != desc->ed_tag.et_guid) {
+ desc->ed_guid = svh->systh_guid;
+ *prog++ = scatter_ops[SCATTER_OP_GUID];
+ }
+#endif
+
+#if defined(MIPI_SYST_PCFG_ENABLE_LOCATION_RECORD)
+ /* location information ? */
+ if ((struct mipi_syst_msglocation*) 0 != loc) {
+ desc->ed_loc = *loc;
+ desc->ed_tag.et_location = 1;
+
+ *prog++ = scatter_ops[SCATTER_OP_LOC_FMT];
+ if (desc->ed_loc.el_format & 0x1)
+ *prog++ = scatter_ops[SCATTER_OP_LOC_64];
+ else
+ *prog++ = scatter_ops[SCATTER_OP_LOC_32];
+ }
+#endif
+
+#if defined(MIPI_SYST_PCFG_LENGTH_FIELD)
+ /* pay load length */
+ if(0 != desc->ed_tag.et_length) {
+ desc->ed_len = len;
+ *prog++ = scatter_ops[SCATTER_OP_LENGTH];
+ }
+#endif
+
+#if defined(MIPI_SYST_PCFG_ENABLE_TIMESTAMP)
+ if (desc->ed_tag.et_timestamp) {
+ /* timestamp present */
+ desc->ed_ts = MIPI_SYST_PLATFORM_CLOCK();
+ *prog++ = scatter_ops[SCATTER_OP_TS];
+ }
+#endif /* defined(MIPI_SYST_PCFG_ENABLE_TIMESTAMP) */
+
+ *prog_ptr = prog;
+}
+#endif
+
+#if defined(MIPI_SYST_PCFG_ENABLE_STRING_API)
+
+/**
+ * Write a string output message
+ *
+ * @param svh SyS-T handle
+ * @param loc Pointer to instrumentation location or null if no location
+ * @param type string message subtype
+ * @param severity severity level (0..7)
+ * @param len number of bytes to emit or 0 to send fixed size 32bytes
+ * @param str pointer to UTF-8 string bytes
+ */
+MIPI_SYST_EXPORT void MIPI_SYST_CALLCONV
+mipi_syst_write_debug_string(struct mipi_syst_handle* svh,
+ struct mipi_syst_msglocation* loc,
+ enum mipi_syst_subtype_string type,
+ enum mipi_syst_severity severity,
+ mipi_syst_u16 len, const char *str)
+{
+ struct mipi_syst_msgdsc desc;
+ struct mipi_syst_scatter_prog prog[MIPI_SYST_SCATTER_PROG_LEN];
+ struct mipi_syst_scatter_prog *prog_ptr = prog;
+ mipi_syst_u64 errmsg;
+
+ if ((struct mipi_syst_handle*)0 == svh)
+ return;
+
+ /* assign tag */
+ desc.ed_tag = svh->systh_tag;
+ desc.ed_tag.et_type = MIPI_SYST_TYPE_STRING;
+ desc.ed_tag.et_subtype = type;
+ desc.ed_tag.et_severity = severity;
+
+ if ((const char *)0 == str) {
+ desc.ed_tag.et_subtype = MIPI_SYST_STRING_INVALIDPARAM;
+ errmsg =
+#if defined(MIPI_SYST_BIG_ENDIAN)
+ 0x286e756c6c290000ull; /* == "(null)\0\0" */
+#else
+ 0x0000296c6c756e28ull; /* == "(null)\0\0" */
+#endif
+ str = (char*)&errmsg;
+ len = 7;
+ }
+ insert_optional_msg_components(svh, loc, len, &desc, &prog_ptr);
+
+ desc.ed_pld.data_var = (const mipi_syst_u8 *) str;
+ *prog_ptr = scatter_ops[SCATTER_OP_PAYLD_VAR];
+ prog_ptr->sso_length = len;
+ ++prog_ptr;
+
+ *prog_ptr = scatter_ops[SCATTER_OP_END];
+
+ ASSERT_CHECK(prog_ptr < &prog[MIPI_SYST_SCATTER_PROG_LEN]);
+
+ /* call IO routine to dump out the message */
+ MIPI_SYST_SCATTER_WRITE(svh, prog, &desc);
+}
+#endif /* #if defined(MIPI_SYST_PCFG_ENABLE_STRING_API) */
+
+#if defined(MIPI_SYST_PCFG_ENABLE_CATID64_API)
+
+/**
+ * Write 64-bit catalog message
+ *
+ * @param svh SyS-T handle
+ * @param loc Pointer to instrumentation location or null
+ * @param severity message severity level (0..7)
+ * @param catid catalog ID
+ */
+MIPI_SYST_EXPORT void MIPI_SYST_CALLCONV
+mipi_syst_write_catalog64_message(struct mipi_syst_handle* svh,
+ struct mipi_syst_msglocation* loc,
+ enum mipi_syst_severity severity, mipi_syst_u64 catid)
+{
+ struct mipi_syst_msgdsc desc;
+ struct mipi_syst_scatter_prog prog[MIPI_SYST_SCATTER_PROG_LEN];
+ struct mipi_syst_scatter_prog *prog_ptr = prog;
+ mipi_syst_u16 paramlen;
+
+ if ((struct mipi_syst_handle*)0 == svh)
+ return;
+
+ /* assign tag */
+ desc.ed_tag = svh->systh_tag;
+ desc.ed_tag.et_type = MIPI_SYST_TYPE_CATALOG;
+ desc.ed_tag.et_severity = severity;
+#if defined(MIPI_SYST_PCFG_ENABLE_64BIT_ADDR)
+ desc.ed_tag.et_subtype = MIPI_SYST_CATALOG_ID64_P64;
+#else
+ desc.ed_tag.et_subtype = MIPI_SYST_CATALOG_ID64_P32;
+#endif
+
+ paramlen = (mipi_syst_u16)
+ (svh->systh_param_count * sizeof(mipi_syst_u32));
+
+ insert_optional_msg_components(
+ svh, loc,
+ sizeof(catid) + paramlen,
+ &desc, &prog_ptr);
+
+ /* cat ID */
+ desc.ed_pld.data_catid.id.sci_64 = catid;
+ *prog_ptr++ = scatter_ops[SCATTER_OP_CATID_64];
+
+ /* parameters (if any) */
+
+ if (0 != paramlen) {
+ mipi_syst_u32 *param;
+ param = svh->systh_param;
+ desc.ed_pld.data_catid.param = param;
+ *prog_ptr = scatter_ops[SCATTER_OP_CATID_ARGS];
+ prog_ptr->sso_length = paramlen;
+ ++prog_ptr;
+#if defined(MIPI_SYST_BIG_ENDIAN)
+ while(paramlen) {
+ *param = MIPI_SYST_HTOLE32(*param);
+ param++;
+ paramlen-=sizeof(mipi_syst_u32);
+ }
+#endif
+ }
+
+ *prog_ptr = scatter_ops[SCATTER_OP_END];
+
+ ASSERT_CHECK(prog_ptr < &prog[MIPI_SYST_SCATTER_PROG_LEN]);
+
+ /* call IO routine to dump out the message */
+ MIPI_SYST_SCATTER_WRITE(svh, prog, &desc);
+}
+
+#endif /* #if defined(MIPI_SYST_PCFG_ENABLE_CATID64_API) */
+
+#if defined(MIPI_SYST_PCFG_ENABLE_CATID32_API)
+
+/**
+ * Write 32-Bit catalog message
+ *
+ * @param svh SyS-T handle
+ * @param loc Pointer to instrumentation location or null
+ * @param severity message severity level (0..7)
+ * @param catid catalog ID
+ */
+MIPI_SYST_EXPORT void MIPI_SYST_CALLCONV
+mipi_syst_write_catalog32_message(struct mipi_syst_handle* svh,
+ struct mipi_syst_msglocation* loc,
+ enum mipi_syst_severity severity, mipi_syst_u32 catid)
+{
+ struct mipi_syst_msgdsc desc;
+ struct mipi_syst_scatter_prog prog[MIPI_SYST_SCATTER_PROG_LEN];
+ struct mipi_syst_scatter_prog *prog_ptr = prog;
+ mipi_syst_u16 paramlen;
+
+ if ((struct mipi_syst_handle*)0 == svh)
+ return;
+
+ /* assign tag */
+ desc.ed_tag = svh->systh_tag;
+ desc.ed_tag.et_type = MIPI_SYST_TYPE_CATALOG;
+ desc.ed_tag.et_severity = severity;
+#if defined(MIPI_SYST_PCFG_ENABLE_64BIT_ADDR)
+ desc.ed_tag.et_subtype = MIPI_SYST_CATALOG_ID32_P64;
+#else
+ desc.ed_tag.et_subtype = MIPI_SYST_CATALOG_ID32_P32;
+#endif
+
+ paramlen = (mipi_syst_u16)
+ (svh->systh_param_count * sizeof(mipi_syst_u32));
+
+ insert_optional_msg_components(
+ svh, loc,
+ sizeof(catid) + paramlen,
+ &desc, &prog_ptr);
+
+ /* cat ID */
+ desc.ed_pld.data_catid.id.sci_32 = catid;
+ *prog_ptr++ = scatter_ops[SCATTER_OP_CATID_32];
+
+ /* parameters (if any) */
+
+ if (0 != paramlen) {
+ mipi_syst_u32 * param;
+ param = svh->systh_param;
+ desc.ed_pld.data_catid.param = param;
+ *prog_ptr = scatter_ops[SCATTER_OP_CATID_ARGS];
+ prog_ptr->sso_length = paramlen;
+ ++prog_ptr;
+#if defined(MIPI_SYST_BIG_ENDIAN)
+ while(paramlen) {
+ *param = MIPI_SYST_HTOLE32(*param);
+ param++;
+ paramlen-=sizeof(mipi_syst_u32);
+ }
+#endif
+ }
+
+ *prog_ptr = scatter_ops[SCATTER_OP_END];
+
+ ASSERT_CHECK(prog_ptr < &prog[MIPI_SYST_SCATTER_PROG_LEN]);
+
+ /* call IO routine to dump out the message */
+ MIPI_SYST_SCATTER_WRITE(svh, prog, &desc);
+}
+
+#endif /* #if defined(MIPI_SYST_PCFG_ENABLE_CATID32_API) */
+
+#if defined(MIPI_SYST_PCFG_ENABLE_WRITE_API)
+
+/**
+ * Write raw data message
+ *
+ * @param svh SyS-T handle
+ * @param loc pointer to instrumentation location or null
+ * @param severity message severity level (0..7)
+ * @param protocol content protocol ID
+ * @param data pointer to raw data
+ * @param length number of bytes to send
+ */
+MIPI_SYST_EXPORT void MIPI_SYST_CALLCONV
+mipi_syst_write_raw_message(struct mipi_syst_handle* svh,
+ struct mipi_syst_msglocation* loc,
+ enum mipi_syst_severity severity,
+ mipi_syst_u8 protocol,
+ const void *data, mipi_syst_u16 length)
+{
+ struct mipi_syst_msgdsc desc;
+ struct mipi_syst_scatter_prog prog[MIPI_SYST_SCATTER_PROG_LEN];
+ struct mipi_syst_scatter_prog *prog_ptr = prog;
+
+ if ((struct mipi_syst_handle*)0 == svh)
+ return;
+
+ /* assign tag */
+ desc.ed_tag = svh->systh_tag;
+ desc.ed_tag.et_type = MIPI_SYST_TYPE_RAW;
+ desc.ed_tag.et_severity = severity;
+ desc.ed_tag.et_subtype = protocol;
+
+ insert_optional_msg_components(svh, loc, length, &desc, &prog_ptr);
+
+ desc.ed_pld.data_var = data;
+ *prog_ptr = scatter_ops[SCATTER_OP_PAYLD_VAR];
+ prog_ptr->sso_length = length;
+ ++prog_ptr;
+
+ *prog_ptr = scatter_ops[SCATTER_OP_END];
+
+ ASSERT_CHECK(prog_ptr < &prog[MIPI_SYST_SCATTER_PROG_LEN]);
+
+ /* call IO routine to dump out the message */
+ MIPI_SYST_SCATTER_WRITE(svh, prog, &desc);
+}
+#endif /* defined(MIPI_SYST_PCFG_ENABLE_WRITE_API) */
+
+#if defined(MIPI_SYST_PCFG_ENABLE_BUILD_API)
+
+/**
+ * Write client build version message
+ *
+ * @param svh SyS-T handle
+ * @param loc pointer to instrumentation location or null
+ * @param severity message severity level (0..7)
+ * @param id 64-Bit version ID
+ * @param text pointer to UTF-8 version text
+ * @param length number of bytes to send
+ */
+MIPI_SYST_EXPORT void MIPI_SYST_CALLCONV
+mipi_syst_write_build_message(struct mipi_syst_handle* svh,
+ struct mipi_syst_msglocation* loc,
+ enum mipi_syst_severity severity,
+ mipi_syst_u64 id,
+ const char *text, mipi_syst_u16 length)
+{
+ struct mipi_syst_msgdsc desc;
+ struct mipi_syst_scatter_prog prog[MIPI_SYST_SCATTER_PROG_LEN];
+ struct mipi_syst_scatter_prog *prog_ptr = prog;
+
+ if ((struct mipi_syst_handle*)0 == svh)
+ return;
+
+ /* assign tag */
+ desc.ed_tag = svh->systh_tag;
+ desc.ed_tag.et_type = MIPI_SYST_TYPE_BUILD;
+ desc.ed_tag.et_severity = severity;
+ desc.ed_tag.et_subtype = MIPI_SYST_BUILD_ID_LONG;
+
+ insert_optional_msg_components(
+ svh, loc, length + sizeof(id), &desc, &prog_ptr);
+
+ desc.ed_pld.data_version.id = id;
+ *prog_ptr = scatter_ops[SCATTER_OP_VER_ID];
+ ++prog_ptr;
+ if (0 != length) {
+ desc.ed_pld.data_version.text = text;
+ *prog_ptr = scatter_ops[SCATTER_OP_VER_TXT];
+ prog_ptr->sso_length = length;
+ ++prog_ptr;
+ }
+ *prog_ptr = scatter_ops[SCATTER_OP_END];
+
+ ASSERT_CHECK(prog_ptr < &prog[MIPI_SYST_SCATTER_PROG_LEN]);
+
+ /* call IO routine to dump out the message */
+ MIPI_SYST_SCATTER_WRITE(svh, prog, &desc);
+}
+#endif /* defined(MIPI_SYST_PCFG_ENABLE_BUILD_API) */
+
+#if defined(MIPI_SYST_PCFG_ENABLE_TIMESTAMP)
+/**
+* Write clock sync message
+*
+* @param svh SyS-T handle
+* @param loc pointer to instrumentation location or null
+* @param fmt clock sync message subtype
+* @param clock_value 64-Bit clock value
+* @param clock_freq 64-Bit clock frequency in herz
+*/
+MIPI_SYST_EXPORT void MIPI_SYST_CALLCONV
+mipi_syst_write_clock(struct mipi_syst_handle* svh,
+ struct mipi_syst_msglocation* loc,
+ enum mipi_syst_subtype_clock fmt,
+ mipi_syst_u64 clock_value,
+ mipi_syst_u64 clock_freq)
+{
+ struct mipi_syst_msgdsc desc;
+ struct mipi_syst_scatter_prog prog[MIPI_SYST_SCATTER_PROG_LEN];
+ struct mipi_syst_scatter_prog *prog_ptr;
+
+ if ((struct mipi_syst_handle*)0 == svh)
+ return;
+
+ prog_ptr = prog;
+
+ /* assign tag */
+ desc.ed_tag = svh->systh_tag;
+ desc.ed_tag.et_subtype = fmt;
+ desc.ed_tag.et_type = MIPI_SYST_TYPE_CLOCK;
+ desc.ed_tag.et_severity = MIPI_SYST_SEVERITY_MAX;
+
+ insert_optional_msg_components(
+ svh, loc,
+ 2*sizeof(mipi_syst_u64),
+ &desc, &prog_ptr);
+
+ desc.ed_pld.data_clock[0] = clock_value;
+ desc.ed_pld.data_clock[1] = clock_freq;
+ *prog_ptr++ = scatter_ops[SCATTER_OP_CLOCK];
+
+ *prog_ptr = scatter_ops[SCATTER_OP_END];
+ ASSERT_CHECK(prog_ptr < &prog[MIPI_SYST_SCATTER_PROG_LEN]);
+
+ MIPI_SYST_SCATTER_WRITE(svh, prog, &desc);
+}
+
+#endif /* defined(MIPI_SYST_PCFG_ENABLE_TIMESTAMP) */
+
+#if defined(MIPI_SYST_PCFG_ENABLE_PRINTF_API)
+
+/* printf requires stdarg from the compiler in use. It is a varargs function*/
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <wchar.h>
+
+#if !defined(MIPI_SYST_PCFG_PRINTF_ARGBUF_SIZE)
+#define MIPI_SYST_PCFG_PRINTF_ARGBUF_SIZE 1024 /* Default 1Kb arg buffer */
+#endif
+
+/** state IDs of the printf format string parser's finite state machine
+ */
+enum FmtScanState {
+ START,
+ PLAINTEXT,
+ PERCENT,
+ FLAGS,
+ WIDTH, WIDTH_NUMBER,
+ PRECISION_DOT, PRECISION_VAL, PRECISION_NUMBER,
+ MODIFIER,
+ MODIFIER_HALF,
+ MODIFIER_LONG,
+ SPECIFIER
+};
+
+/** format modifier types
+ */
+enum Modifier {
+ MOD_NONE, MOD_HH, MOD_H, MOD_L, MOD_LL, MOD_J, MOD_Z, MOD_T, MOD_LD
+};
+
+/** parser result codes
+ *
+ */
+enum ReturnCodes {
+ FMT_PARSE_OK = 1,
+ FMT_PARSE_ARG_BUFFER_TOO_SMALL = -1,
+ FMT_PARSE_UNSUPPORTED_FORMAT = -2
+};
+
+/* Helper macro to copy an argument from the arguments into the
+ * payload buffer.
+ *
+ * TOTYPE is the data type that gets stored in the messages's arg buffer
+ * FROMTYPE is the data type taken from the printf stack via varags
+ */
+#define COPY_ARG_DOUBLE(TOTYPE, FROMTYPE) \
+ do { \
+ union {mipi_syst_u64 v; TOTYPE d;} val; \
+ val.d = (TOTYPE)va_arg(args, FROMTYPE); \
+ if (argp + sizeof(TOTYPE) < argEob) { \
+ val.v = MIPI_SYST_HTOLE64(val.v); \
+ *((TOTYPE *)argp) = val.d; \
+ argp += sizeof(TOTYPE); \
+ } else { \
+ return FMT_PARSE_ARG_BUFFER_TOO_SMALL; \
+ } \
+ } while(0)
+
+#define COPY_ARG32(TOTYPE, FROMTYPE) \
+ do { \
+ if (argp + sizeof(TOTYPE) < argEob) { \
+ *((TOTYPE *)argp) = (TOTYPE)MIPI_SYST_HTOLE32(va_arg(args, FROMTYPE)); \
+ argp += sizeof(TOTYPE); \
+ } else { \
+ return FMT_PARSE_ARG_BUFFER_TOO_SMALL; \
+ } \
+ } while(0)
+
+#define COPY_ARG64(TOTYPE, FROMTYPE) \
+ do { \
+ if (argp + sizeof(TOTYPE) < argEob) { \
+ *((TOTYPE *)argp) = (TOTYPE)MIPI_SYST_HTOLE64(va_arg(args, FROMTYPE));\
+ argp += sizeof(TOTYPE); \
+ } else { \
+ return FMT_PARSE_ARG_BUFFER_TOO_SMALL; \
+ } \
+ } while(0)
+
+/** Create the payload buffer for a printf format
+ *
+ * The payload of a printf message, starts with an UTF-8 string,
+ * which becomes the printf format. Depending on the format string, further
+ * parameters follow the format string using the following rules:
+ *
+ * All printf arguments follow the format string without alignment bytes added.
+ * Strings for the '%s' format specifier are embedded as UTF-8 strings with
+ * 0-byte termination into the payload.
+ * printf arguments use the binary data layout as defined in the table below.
+ *
+ * Data Type | 32 Bit Platform | 64 Bit Platform
+ * --------------------------|--------------------|---------------------------
+ * int, unsigned int | 32 Bits | 32 Bits
+ * long, unsigned long | 32 Bits | 64 Bits
+ * long long, unsinged long long|64 Bits | 64 Bits
+ * size_t | 32 Bits | 64 Bits
+ * ptrdiff_t | 32 Bits | 64 Bits
+ * float double, long double | 64 Bits | 64 Bits
+ * char, unsigned char | 32 Bits | 32 Bits
+ * wchar_t | 32 Bits | 32 Bits
+ * Addresses(pointers) | 32 Bits | 64 Bits
+ * Strings (char *) |UTF-8, 0-terminated | UTF-8, 0-terminated
+ *
+ * The format string follows the C99 definition which can contain format
+ * specifier following this pattern:
+ *
+ * %[flags][width][.precision][length]specifier
+ *
+ * This function 'only' converts the fmt and arguments into a message payload.
+ * The actual formatting of the data into a string is done by the receiving
+ * trace decoder.
+ *
+ * @param buffer memory buffer filled with argument data
+ * @param size # of bytes in buffer
+ * @param fmt printf format string
+ * @param args printf varags
+
+ */
+static int buildPrintfPayload(
+ char * buffer,
+ mipi_syst_u32 size,
+ const char * fmt,
+ va_list args)
+{
+ char * argEob;
+ char * argp;
+ const char * fmtp;
+ enum FmtScanState state;
+ enum Modifier modifier;
+
+ if (0 == fmt) return FMT_PARSE_UNSUPPORTED_FORMAT;
+
+ argp = buffer;
+ argEob = buffer + size; /* end of buffer address */
+ fmtp = fmt;
+
+ /* copy argument string to start of payload buffer
+ */
+ while (argp < argEob) {
+ if( 0 == (*argp++ = *fmtp++)) break;
+ }
+ if (argp == argEob) return FMT_PARSE_ARG_BUFFER_TOO_SMALL;
+
+ fmtp = fmt;
+ state = START;
+ modifier = MOD_NONE;
+
+ /* loop over the arguments in the format and full the arg buffer
+ */
+ while( *fmtp != 0 )
+ {
+ switch(state) {
+ case START:
+ modifier = MOD_NONE;
+
+ state = PLAINTEXT;
+ ; /* deliberate fall through */
+
+ case PLAINTEXT:
+ if (*fmtp == '%') {
+ state = PERCENT;
+ }
+ break;
+
+ case PERCENT:
+ if (*fmtp == '%') { /* '%%' is not a format, but the % char */
+ state = PLAINTEXT;
+ } else {
+ /* arg fmt definition is starting */
+ state = FLAGS;
+ continue;
+ }
+ break;
+
+ case FLAGS:
+ switch(*fmtp) {
+ case '-':
+ case '+':
+ case ' ':
+ case '#':
+ case '0':
+ break;
+ default:
+ state = WIDTH;
+ continue;
+ }
+ break;
+
+ case WIDTH:
+ if (*fmtp == '*') {
+ COPY_ARG32(mipi_syst_s32, int);
+ state = PRECISION_DOT;
+ } else {
+ state = WIDTH_NUMBER;
+ continue;
+ }
+ break;
+
+ case WIDTH_NUMBER:
+ if (*fmtp < '0' || *fmtp > '9') { /* !isdigit */
+ state = PRECISION_DOT;
+ continue;
+ }
+ break;
+
+ case PRECISION_DOT:
+ if (*fmtp == '.') {
+ state = PRECISION_VAL;
+ } else {
+ state = MODIFIER;
+ continue;
+ }
+ break;
+
+ case PRECISION_VAL:
+ if (*fmtp == '*') {
+ COPY_ARG32(mipi_syst_s32, int);
+ state = MODIFIER;
+ } else {
+ state = PRECISION_NUMBER;
+ continue;
+ }
+ break;
+
+ case PRECISION_NUMBER:
+ if (*fmtp < '0' || *fmtp > '9') { /* !isdigit */
+ state = MODIFIER;
+ continue;
+ }
+ break;
+
+ case MODIFIER:
+ state = SPECIFIER;
+
+ switch(*fmtp){
+ case 'h':
+ modifier = MOD_H;
+ state = MODIFIER_HALF;
+ break;
+ case 'l':
+ modifier = MOD_L;
+ state = MODIFIER_LONG;
+ break;
+ case 'j':
+ modifier = MOD_J;
+ break;
+ case 'z':
+ modifier = MOD_Z;
+ break;
+ case 't':
+ modifier = MOD_T;
+ break;
+ case 'L':
+ modifier = MOD_LD;
+ break;
+ default:
+ continue;
+ }
+ break;
+
+ case MODIFIER_HALF:
+ state = SPECIFIER;
+ if (*fmtp == 'h') {
+ modifier = MOD_HH;
+ break;
+ } else {
+ continue;
+ }
+ break;
+
+
+ case MODIFIER_LONG:
+ state = SPECIFIER;
+ if (*fmtp == 'l') {
+ modifier = MOD_LL;
+ break;
+ } else {
+ continue;
+ }
+
+ case SPECIFIER:
+ {
+ switch(*fmtp) {
+ case 'd':
+ case 'i':
+ case 'u':
+ case 'o':
+ case 'x':
+ case 'X':
+ switch(modifier) {
+ case MOD_L:
+#if defined(MIPI_SYST_PCFG_ENABLE_64BIT_ADDR)
+ COPY_ARG64(mipi_syst_u64, long);
+#else
+ COPY_ARG32(mipi_syst_u32, unsigned long);
+#endif
+ break;
+ case MOD_LL:
+ case MOD_J:
+ COPY_ARG64(mipi_syst_u64, unsigned long long);
+ break;
+ case MOD_Z:
+#if defined(MIPI_SYST_PCFG_ENABLE_64BIT_ADDR)
+ COPY_ARG64(mipi_syst_u64, size_t);
+#else
+ COPY_ARG32(mipi_syst_u32, size_t);
+#endif
+ break;
+ case MOD_T:
+#if defined(MIPI_SYST_PCFG_ENABLE_64BIT_ADDR)
+ COPY_ARG64(mipi_syst_s64, ptrdiff_t);
+#else
+ COPY_ARG32(mipi_syst_s32, ptrdiff_t);
+#endif
+ break;
+ default:
+ COPY_ARG32(mipi_syst_u32, unsigned int);
+ break;
+ }
+ state = START;
+ break;
+ case 'f':
+ case 'F':
+ case 'e':
+ case 'E':
+ case 'g':
+ case 'G':
+ case 'a':
+ case 'A':
+ if (modifier == MOD_LD) {
+ COPY_ARG_DOUBLE(double, long double); /* only double*/
+ } else {
+ COPY_ARG_DOUBLE(double, double);
+ }
+ break;
+ case 'c':
+ if (modifier == MOD_L) {
+ COPY_ARG32(mipi_syst_u32, wchar_t);
+ } else {
+ COPY_ARG32(mipi_syst_u32, int);
+ }
+ break;
+ case 'p':
+ case 'n':
+#if defined(MIPI_SYST_PCFG_ENABLE_64BIT_ADDR)
+ COPY_ARG64(mipi_syst_u64, void *);
+#else
+ COPY_ARG32(mipi_syst_u32, void *);
+#endif
+ break;
+ case 's':
+ {
+ /* Embed string with 0-byte into arg buffer */
+ const char * p;
+ p = va_arg(args, char *);
+ while (argp < argEob) {
+ if (0 == (*argp++ = *p++)) {
+ break;
+ }
+ if (argp == argEob) {
+ return FMT_PARSE_ARG_BUFFER_TOO_SMALL;
+ }
+ }
+ }
+ break;
+
+ default:
+ return FMT_PARSE_UNSUPPORTED_FORMAT;
+ break;
+ }
+ state = START;
+ }
+ break;
+ }
+ ++fmtp;
+ }
+
+ if (state == START || state == PLAINTEXT) {
+ return (int)(argp - buffer);
+ } else {
+ return FMT_PARSE_UNSUPPORTED_FORMAT;
+ }
+}
+#if defined(MIPI_SYST_PCFG_ENABLE_CATID64_API) || defined(MIPI_SYST_PCFG_ENABLE_CATID32_API)
+static int buildCatalogPayload(
+ mipi_syst_u8 * buffer,
+ mipi_syst_u32 size,
+ va_list args)
+{
+ mipi_syst_u8 * argEob;
+ mipi_syst_u8 * argp;
+ int argType;
+
+ argp = buffer;
+ argEob = buffer + size; /* end of buffer address */
+
+
+ /* loop over the argument types
+ */
+ for(argType = va_arg(args, int);
+ argType != 0;
+ argType = va_arg(args, int))
+ {
+ switch(argType) {
+ case _MIPI_SYST_CATARG_D:
+ COPY_ARG32(mipi_syst_u32, unsigned int);
+ break;
+ case _MIPI_SYST_CATARG_LD:
+#if defined(MIPI_SYST_PCFG_ENABLE_64BIT_ADDR)
+ COPY_ARG64(mipi_syst_u64, long);
+#else
+ COPY_ARG32(mipi_syst_u32, unsigned long);
+#endif
+ break;
+
+ case _MIPI_SYST_CATARG_LLD:
+ COPY_ARG64(mipi_syst_u64, unsigned long long);
+ break;
+
+ case _MIPI_SYST_CATARG_ZD:
+#if defined(MIPI_SYST_PCFG_ENABLE_64BIT_ADDR)
+ COPY_ARG64(mipi_syst_u64, size_t);
+#else
+ COPY_ARG32(mipi_syst_u32, size_t);
+#endif
+ break;
+
+ case _MIPI_SYST_CATARG_TD:
+#if defined(MIPI_SYST_PCFG_ENABLE_64BIT_ADDR)
+ COPY_ARG64(mipi_syst_s64, ptrdiff_t);
+#else
+ COPY_ARG32(mipi_syst_s32, ptrdiff_t);
+#endif
+ break;
+
+ case _MIPI_SYST_CATARG_F:
+ COPY_ARG_DOUBLE(double, double);
+ break;
+ case _MIPI_SYST_CATARG_LF:
+ COPY_ARG_DOUBLE(double, long double);
+ break;
+ case _MIPI_SYST_CATARG_C:
+ COPY_ARG32(mipi_syst_u32, int);
+ break;
+ case _MIPI_SYST_CATARG_HHD:
+ COPY_ARG32(mipi_syst_u32, int);
+ break;
+ case _MIPI_SYST_CATARG_LC:
+ COPY_ARG32(mipi_syst_u32, wint_t);
+ break;
+
+ case _MIPI_SYST_CATARG_P:
+#if defined(MIPI_SYST_PCFG_ENABLE_64BIT_ADDR)
+ COPY_ARG64(mipi_syst_u64, void *);
+#else
+ COPY_ARG32(mipi_syst_u32, void *);
+#endif
+ break;
+
+ case _MIPI_SYST_CATARG_CSTR:
+ {
+ const char * p;
+ p = va_arg(args, char *);
+ while (argp < argEob) {
+ if (0 == (*argp++ = *p++)) {
+ break;
+ }
+ if (argp == argEob) {
+ return FMT_PARSE_ARG_BUFFER_TOO_SMALL;
+ }
+ }
+ }
+ break;
+
+ default:
+ return FMT_PARSE_UNSUPPORTED_FORMAT;
+ break;
+ }
+ }
+
+ return (int)(argp - buffer);
+}
+
+#endif // #if defined(MIPI_SYST_PCFG_ENABLE_CATIDxx_API)
+
+/**
+ * Write a printf message
+ *
+ * @param svh SyS-T handle
+ * @param loc Pointer to instrumentation location or null if no location
+ * @param severity severity level (0..7)
+ * @param fmt pointer to UTF-8 string bytes
+ * @param ... optional format arguments
+ */
+MIPI_SYST_EXPORT void MIPI_SYST_CALLCONV
+ mipi_syst_write_printf_string(struct mipi_syst_handle* svh,
+ struct mipi_syst_msglocation* loc,
+ enum mipi_syst_severity severity,
+ const char *fmt,
+ ...)
+{
+ char argBuf[MIPI_SYST_PCFG_PRINTF_ARGBUF_SIZE];
+ int len;
+ va_list args;
+ struct mipi_syst_msgdsc desc;
+ struct mipi_syst_scatter_prog prog[MIPI_SYST_SCATTER_PROG_LEN];
+ struct mipi_syst_scatter_prog *prog_ptr = prog;
+ mipi_syst_u64 errmsg;
+
+ if ((struct mipi_syst_handle*)0 == svh)
+ return;
+
+ /* assign tag */
+ desc.ed_tag = svh->systh_tag;
+ desc.ed_tag.et_type = MIPI_SYST_TYPE_STRING;
+#if defined(MIPI_SYST_PCFG_ENABLE_64BIT_ADDR)
+ desc.ed_tag.et_subtype = MIPI_SYST_STRING_PRINTF_64;
+#else
+ desc.ed_tag.et_subtype = MIPI_SYST_STRING_PRINTF_32;
+#endif
+ desc.ed_tag.et_severity = severity;
+
+ va_start(args, fmt);
+ len = buildPrintfPayload(argBuf, sizeof(argBuf), fmt, args);
+ va_end(args);
+
+ if (len <= 0 ) {
+ /* Invalid format, send up to 32 bytes from the offending format string
+ * as string message with tag "invalid parameter" instead
+ */
+ desc.ed_tag.et_subtype = MIPI_SYST_STRING_INVALIDPARAM;
+ errmsg =
+#if defined(MIPI_SYST_BIG_ENDIAN)
+ 0x286e756c6c290000ull; /* == "(null)\0\0" */
+#else
+ 0x0000296c6c756e28ull; /* == "(null)\0\0" */
+#endif
+ fmt = fmt ? fmt : (char*)&errmsg;
+
+ for (len = 0; len < 32;)
+ if (0 == fmt[len++]) break;
+ } else {
+ fmt = argBuf;
+ }
+ insert_optional_msg_components(svh, loc, (mipi_syst_u16)len, &desc, &prog_ptr);
+
+ *prog_ptr = scatter_ops[SCATTER_OP_PAYLD_VAR];
+ desc.ed_pld.data_var = (const mipi_syst_u8 *) fmt;
+ prog_ptr->sso_length = (mipi_syst_u16)len;
+ ++prog_ptr;
+ *prog_ptr = scatter_ops[SCATTER_OP_END];
+
+ ASSERT_CHECK(prog_ptr < &prog[MIPI_SYST_SCATTER_PROG_LEN]);
+
+ /* call IO routine to dump out the message */
+ MIPI_SYST_SCATTER_WRITE(svh, prog, &desc);
+}
+
+#if defined(MIPI_SYST_PCFG_ENABLE_CATID64_API)
+
+/**
+ * Write a printf catalog message with 64bit ID
+ *
+ * @param svh SyS-T handle
+ * @param loc Pointer to instrumentation location or null if no location
+ * @param severity severity level (0..7)
+ * @param id catalog id
+ */
+MIPI_SYST_EXPORT void MIPI_SYST_CALLCONV
+ mipi_syst_write_printf_catalog64(struct mipi_syst_handle* svh,
+ struct mipi_syst_msglocation* loc,
+ enum mipi_syst_severity severity,
+ mipi_syst_u64 id,
+ ...)
+{
+ mipi_syst_u8 argBuf[MIPI_SYST_PCFG_PRINTF_ARGBUF_SIZE+sizeof(id)];
+ int len;
+ va_list args;
+ struct mipi_syst_msgdsc desc;
+ struct mipi_syst_scatter_prog prog[MIPI_SYST_SCATTER_PROG_LEN];
+ struct mipi_syst_scatter_prog *prog_ptr = prog;
+ mipi_syst_u64 errmsg;
+
+ if ((struct mipi_syst_handle*)0 == svh)
+ return;
+
+ /* assign tag */
+ desc.ed_tag = svh->systh_tag;
+ desc.ed_tag.et_type = MIPI_SYST_TYPE_CATALOG;
+#if defined(MIPI_SYST_PCFG_ENABLE_64BIT_ADDR)
+ desc.ed_tag.et_subtype = MIPI_SYST_CATALOG_ID64_P64;
+#else
+ desc.ed_tag.et_subtype = MIPI_SYST_CATALOG_ID64_P32;
+#endif
+ desc.ed_tag.et_severity = severity;
+
+ va_start(args, id);
+ len = buildCatalogPayload(argBuf+sizeof(id),
+ MIPI_SYST_PCFG_PRINTF_ARGBUF_SIZE,
+ args);
+ va_end(args);
+
+ if (len < 0 ) {
+ char * msg;
+ errmsg =
+#if defined(MIPI_SYST_BIG_ENDIAN)
+ 0x6361746172670000ull; /* = "catarg\0\0" */
+#else
+ 0x0000677261746163ull; /* = "catarg\0\0" */
+#endif
+ /* Invalid parameter list */
+ desc.ed_tag.et_type = MIPI_SYST_TYPE_STRING;
+ desc.ed_tag.et_subtype = MIPI_SYST_STRING_INVALIDPARAM;
+ len = 0;
+ msg = (char*)&errmsg;
+ while (0 != (argBuf[len++] = *msg++));
+ } else {
+ *(mipi_syst_u64*)argBuf = MIPI_SYST_HTOLE64(id);
+ len += sizeof(id);
+ }
+
+ insert_optional_msg_components(svh, loc, (mipi_syst_u16)len, &desc, &prog_ptr);
+
+ *prog_ptr = scatter_ops[SCATTER_OP_PAYLD_VAR];
+ desc.ed_pld.data_var = (const mipi_syst_u8 *) argBuf;
+ prog_ptr->sso_length = (mipi_syst_u16)len;
+ ++prog_ptr;
+ *prog_ptr = scatter_ops[SCATTER_OP_END];
+
+ ASSERT_CHECK(prog_ptr < &prog[MIPI_SYST_SCATTER_PROG_LEN]);
+
+ /* call IO routine to dump out the message */
+ MIPI_SYST_SCATTER_WRITE(svh, prog, &desc);
+}
+#endif // #if defined(MIPI_SYST_PCFG_ENABLE_CATID64_API)
+#if defined(MIPI_SYST_PCFG_ENABLE_CATID32_API)
+
+/**
+ * Write a printf catalog message with 32bit ID
+ *
+ * @param svh SyS-T handle
+ * @param loc Pointer to instrumentation location or null if no location
+ * @param severity severity level (0..7)
+ * @param id catalog id
+ */
+MIPI_SYST_EXPORT void MIPI_SYST_CALLCONV
+ mipi_syst_write_printf_catalog32(struct mipi_syst_handle* svh,
+ struct mipi_syst_msglocation* loc,
+ enum mipi_syst_severity severity,
+ mipi_syst_u32 id,
+ ...)
+{
+ mipi_syst_u8 argBuf[MIPI_SYST_PCFG_PRINTF_ARGBUF_SIZE+sizeof(id)];
+ int len;
+ va_list args;
+ struct mipi_syst_msgdsc desc;
+ struct mipi_syst_scatter_prog prog[MIPI_SYST_SCATTER_PROG_LEN];
+ struct mipi_syst_scatter_prog *prog_ptr = prog;
+ mipi_syst_u64 errmsg;
+
+ if ((struct mipi_syst_handle*)0 == svh)
+ return;
+
+ /* assign tag */
+ desc.ed_tag = svh->systh_tag;
+ desc.ed_tag.et_type = MIPI_SYST_TYPE_CATALOG;
+#if defined(MIPI_SYST_PCFG_ENABLE_64BIT_ADDR)
+ desc.ed_tag.et_subtype = MIPI_SYST_CATALOG_ID32_P64;
+#else
+ desc.ed_tag.et_subtype = MIPI_SYST_CATALOG_ID32_P32;
+#endif
+ desc.ed_tag.et_severity = severity;
+
+ va_start(args, id);
+ len = buildCatalogPayload(argBuf+sizeof(id),
+ MIPI_SYST_PCFG_PRINTF_ARGBUF_SIZE,
+ args);
+ va_end(args);
+
+ if (len < 0 ) {
+ char * msg;
+ errmsg =
+#if defined(MIPI_SYST_BIG_ENDIAN)
+ 0x6361746172670000ull; /* = "catarg\0\0" */
+#else
+ 0x0000677261746163ull; /* = "catarg\0\0" */
+#endif
+ /* Invalid parameter list */
+ desc.ed_tag.et_type = MIPI_SYST_TYPE_STRING;
+ desc.ed_tag.et_subtype = MIPI_SYST_STRING_INVALIDPARAM;
+ len = 0;
+ msg = (char*)&errmsg;
+ while (0 != (argBuf[len++] = *msg++));
+ } else {
+ *(mipi_syst_u32*)argBuf = MIPI_SYST_HTOLE32(id);
+ len += sizeof(id);
+ }
+
+ insert_optional_msg_components(svh, loc, (mipi_syst_u16)len, &desc, &prog_ptr);
+
+ *prog_ptr = scatter_ops[SCATTER_OP_PAYLD_VAR];
+ desc.ed_pld.data_var = (const mipi_syst_u8 *) argBuf;
+ prog_ptr->sso_length = (mipi_syst_u16)len;
+ ++prog_ptr;
+ *prog_ptr = scatter_ops[SCATTER_OP_END];
+
+ ASSERT_CHECK(prog_ptr < &prog[MIPI_SYST_SCATTER_PROG_LEN]);
+
+ /* call IO routine to dump out the message */
+ MIPI_SYST_SCATTER_WRITE(svh, prog, &desc);
+}
+#endif // #if defined(MIPI_SYST_PCFG_ENABLE_CATID32_API)
+#endif /* #if defined(MIPI_SYST_PCFG_ENABLE_PRINTF_API) */ \ No newline at end of file
diff --git a/library/src/mipi_syst_compiler.c b/library/src/mipi_syst_compiler.c
new file mode 100644
index 0000000..a03c1a2
--- /dev/null
+++ b/library/src/mipi_syst_compiler.c
@@ -0,0 +1,78 @@
+/*
+Copyright (c) 2018, MIPI Alliance, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+* Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+* Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+ * Contributors:
+ * Norbert Schulz (Intel Corporation) - Initial API and implementation
+ */
+
+ /* Compiler dependent code */
+
+#include "mipi_syst.h"
+
+#if defined(_WIN32) /* MSVC Compiler section */
+
+#include <intrin.h>
+#pragma intrinsic(_ReturnAddress)
+
+#if defined(MIPI_SYST_PCFG_ENABLE_LOCATION_ADDRESS)
+/**
+ * Return the instruction pointer address of the instruction
+ * that follows this function. It is used to compute
+ * location information for SyS-T instrumentation calls.
+ * These are the calls that end with the _LOCADDR suffix.
+ */
+MIPI_SYST_EXPORT void *MIPI_SYST_CALLCONV mipi_syst_return_addr()
+{
+ return _ReturnAddress();
+}
+#endif /* defined(MIPI_SYST_PCFG_ENABLE_LOCATION_ADDRESS) */
+
+#elif defined(__GNUC__) /* GNU-C Compiler section */
+
+#if defined(MIPI_SYST_PCFG_ENABLE_LOCATION_ADDRESS)
+/**
+ * Return the instruction pointer address of the instruction
+ * that follows this function. It is used to compute
+ * location information for SyS-T instrumentation calls.
+ * These are the calls that end with the _LOCADDR suffix.
+ */
+MIPI_SYST_EXPORT void *MIPI_SYST_CALLCONV mipi_syst_return_addr()
+{
+ return __builtin_return_address(0);
+}
+#endif
+
+#else
+#error unknown compiler, copy and adapt one of the sections above
+#endif \ No newline at end of file
diff --git a/library/src/mipi_syst_crc32.c b/library/src/mipi_syst_crc32.c
new file mode 100644
index 0000000..65e3451
--- /dev/null
+++ b/library/src/mipi_syst_crc32.c
@@ -0,0 +1,313 @@
+/*
+Copyright (c) 2018, MIPI Alliance, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+* Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+* Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+ * Contributors:
+ * Norbert Schulz (Intel Corporation) - Initial API and implementation
+ */
+
+#include "mipi_syst.h"
+
+#if defined(MIPI_SYST_PCFG_ENABLE_CHECKSUM) && !defined(MIPI_SYST_CRC_INTRINSIC)
+
+/*
+ * Pre-computed CRC-C values for all 8-bit values using
+ * polynomial 0x1EDC6F41 (Castagnoli).
+ */
+
+const mipi_syst_u32 mipi_syst_crc_table[256] = {
+ 0x00000000,
+ 0xF26B8303,
+ 0xE13B70F7,
+ 0x1350F3F4,
+ 0xC79A971F,
+ 0x35F1141C,
+ 0x26A1E7E8,
+ 0xD4CA64EB,
+ 0x8AD958CF,
+ 0x78B2DBCC,
+ 0x6BE22838,
+ 0x9989AB3B,
+ 0x4D43CFD0,
+ 0xBF284CD3,
+ 0xAC78BF27,
+ 0x5E133C24,
+ 0x105EC76F,
+ 0xE235446C,
+ 0xF165B798,
+ 0x030E349B,
+ 0xD7C45070,
+ 0x25AFD373,
+ 0x36FF2087,
+ 0xC494A384,
+ 0x9A879FA0,
+ 0x68EC1CA3,
+ 0x7BBCEF57,
+ 0x89D76C54,
+ 0x5D1D08BF,
+ 0xAF768BBC,
+ 0xBC267848,
+ 0x4E4DFB4B,
+ 0x20BD8EDE,
+ 0xD2D60DDD,
+ 0xC186FE29,
+ 0x33ED7D2A,
+ 0xE72719C1,
+ 0x154C9AC2,
+ 0x061C6936,
+ 0xF477EA35,
+ 0xAA64D611,
+ 0x580F5512,
+ 0x4B5FA6E6,
+ 0xB93425E5,
+ 0x6DFE410E,
+ 0x9F95C20D,
+ 0x8CC531F9,
+ 0x7EAEB2FA,
+ 0x30E349B1,
+ 0xC288CAB2,
+ 0xD1D83946,
+ 0x23B3BA45,
+ 0xF779DEAE,
+ 0x05125DAD,
+ 0x1642AE59,
+ 0xE4292D5A,
+ 0xBA3A117E,
+ 0x4851927D,
+ 0x5B016189,
+ 0xA96AE28A,
+ 0x7DA08661,
+ 0x8FCB0562,
+ 0x9C9BF696,
+ 0x6EF07595,
+ 0x417B1DBC,
+ 0xB3109EBF,
+ 0xA0406D4B,
+ 0x522BEE48,
+ 0x86E18AA3,
+ 0x748A09A0,
+ 0x67DAFA54,
+ 0x95B17957,
+ 0xCBA24573,
+ 0x39C9C670,
+ 0x2A993584,
+ 0xD8F2B687,
+ 0x0C38D26C,
+ 0xFE53516F,
+ 0xED03A29B,
+ 0x1F682198,
+ 0x5125DAD3,
+ 0xA34E59D0,
+ 0xB01EAA24,
+ 0x42752927,
+ 0x96BF4DCC,
+ 0x64D4CECF,
+ 0x77843D3B,
+ 0x85EFBE38,
+ 0xDBFC821C,
+ 0x2997011F,
+ 0x3AC7F2EB,
+ 0xC8AC71E8,
+ 0x1C661503,
+ 0xEE0D9600,
+ 0xFD5D65F4,
+ 0x0F36E6F7,
+ 0x61C69362,
+ 0x93AD1061,
+ 0x80FDE395,
+ 0x72966096,
+ 0xA65C047D,
+ 0x5437877E,
+ 0x4767748A,
+ 0xB50CF789,
+ 0xEB1FCBAD,
+ 0x197448AE,
+ 0x0A24BB5A,
+ 0xF84F3859,
+ 0x2C855CB2,
+ 0xDEEEDFB1,
+ 0xCDBE2C45,
+ 0x3FD5AF46,
+ 0x7198540D,
+ 0x83F3D70E,
+ 0x90A324FA,
+ 0x62C8A7F9,
+ 0xB602C312,
+ 0x44694011,
+ 0x5739B3E5,
+ 0xA55230E6,
+ 0xFB410CC2,
+ 0x092A8FC1,
+ 0x1A7A7C35,
+ 0xE811FF36,
+ 0x3CDB9BDD,
+ 0xCEB018DE,
+ 0xDDE0EB2A,
+ 0x2F8B6829,
+ 0x82F63B78,
+ 0x709DB87B,
+ 0x63CD4B8F,
+ 0x91A6C88C,
+ 0x456CAC67,
+ 0xB7072F64,
+ 0xA457DC90,
+ 0x563C5F93,
+ 0x082F63B7,
+ 0xFA44E0B4,
+ 0xE9141340,
+ 0x1B7F9043,
+ 0xCFB5F4A8,
+ 0x3DDE77AB,
+ 0x2E8E845F,
+ 0xDCE5075C,
+ 0x92A8FC17,
+ 0x60C37F14,
+ 0x73938CE0,
+ 0x81F80FE3,
+ 0x55326B08,
+ 0xA759E80B,
+ 0xB4091BFF,
+ 0x466298FC,
+ 0x1871A4D8,
+ 0xEA1A27DB,
+ 0xF94AD42F,
+ 0x0B21572C,
+ 0xDFEB33C7,
+ 0x2D80B0C4,
+ 0x3ED04330,
+ 0xCCBBC033,
+ 0xA24BB5A6,
+ 0x502036A5,
+ 0x4370C551,
+ 0xB11B4652,
+ 0x65D122B9,
+ 0x97BAA1BA,
+ 0x84EA524E,
+ 0x7681D14D,
+ 0x2892ED69,
+ 0xDAF96E6A,
+ 0xC9A99D9E,
+ 0x3BC21E9D,
+ 0xEF087A76,
+ 0x1D63F975,
+ 0x0E330A81,
+ 0xFC588982,
+ 0xB21572C9,
+ 0x407EF1CA,
+ 0x532E023E,
+ 0xA145813D,
+ 0x758FE5D6,
+ 0x87E466D5,
+ 0x94B49521,
+ 0x66DF1622,
+ 0x38CC2A06,
+ 0xCAA7A905,
+ 0xD9F75AF1,
+ 0x2B9CD9F2,
+ 0xFF56BD19,
+ 0x0D3D3E1A,
+ 0x1E6DCDEE,
+ 0xEC064EED,
+ 0xC38D26C4,
+ 0x31E6A5C7,
+ 0x22B65633,
+ 0xD0DDD530,
+ 0x0417B1DB,
+ 0xF67C32D8,
+ 0xE52CC12C,
+ 0x1747422F,
+ 0x49547E0B,
+ 0xBB3FFD08,
+ 0xA86F0EFC,
+ 0x5A048DFF,
+ 0x8ECEE914,
+ 0x7CA56A17,
+ 0x6FF599E3,
+ 0x9D9E1AE0,
+ 0xD3D3E1AB,
+ 0x21B862A8,
+ 0x32E8915C,
+ 0xC083125F,
+ 0x144976B4,
+ 0xE622F5B7,
+ 0xF5720643,
+ 0x07198540,
+ 0x590AB964,
+ 0xAB613A67,
+ 0xB831C993,
+ 0x4A5A4A90,
+ 0x9E902E7B,
+ 0x6CFBAD78,
+ 0x7FAB5E8C,
+ 0x8DC0DD8F,
+ 0xE330A81A,
+ 0x115B2B19,
+ 0x020BD8ED,
+ 0xF0605BEE,
+ 0x24AA3F05,
+ 0xD6C1BC06,
+ 0xC5914FF2,
+ 0x37FACCF1,
+ 0x69E9F0D5,
+ 0x9B8273D6,
+ 0x88D28022,
+ 0x7AB90321,
+ 0xAE7367CA,
+ 0x5C18E4C9,
+ 0x4F48173D,
+ 0xBD23943E,
+ 0xF36E6F75,
+ 0x0105EC76,
+ 0x12551F82,
+ 0xE03E9C81,
+ 0x34F4F86A,
+ 0xC69F7B69,
+ 0xD5CF889D,
+ 0x27A40B9E,
+ 0x79B737BA,
+ 0x8BDCB4B9,
+ 0x988C474D,
+ 0x6AE7C44E,
+ 0xBE2DA0A5,
+ 0x4C4623A6,
+ 0x5F16D052,
+ 0xAD7D5351
+};
+
+
+#if !defined(MIPI_SYST_PCFG_ENABLE_INLINE)
+#define MIPI_SYST_PCFG_ENABLE_INLINE
+#include "mipi_syst/crc32.h"
+#endif
+
+#endif /* defined(MIPI_SYST_PCFG_ENABLE_CHECKSUM) && !defined(MIPI_SYST_CRC_INTRINSIC)) */ \ No newline at end of file
diff --git a/library/src/mipi_syst_init.c b/library/src/mipi_syst_init.c
new file mode 100644
index 0000000..90ba5a5
--- /dev/null
+++ b/library/src/mipi_syst_init.c
@@ -0,0 +1,204 @@
+/*
+Copyright (c) 2018, MIPI Alliance, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+* Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+* Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+ * Contributors:
+ * Norbert Schulz (Intel Corporation) - Initial API and implementation
+ */
+
+#include "mipi_syst.h"
+#include "mipi_syst/message.h"
+
+/**
+ * SyS-T global state
+ */
+static struct mipi_syst_header syst_hdr = { 0 };
+
+static union mipi_syst_null_init {
+ struct mipi_syst_handle handle;
+ struct mipi_syst_header header;
+} zero = { {0} }; /* for initializations */
+
+#if !defined(MIPI_SYST_PCFG_ENABLE_DEFAULT_SCATTER_WRITE)
+/**
+ * null-device style default output function
+ */
+static void nullWriter(struct mipi_syst_handle* systh,
+ struct mipi_syst_scatter_prog scatterprog, const void *pdesc)
+{
+}
+#endif
+
+/**
+ * Initialize the SyS-T library.
+ *
+ * This function must be called during the start of the platform before any
+ * other instrumentation library call. The function initializes the global
+ * state data necessary for the library to execute. Passing NULL as state
+ * means using the shared global state singleton. Passing a valid pointer
+ * allows using multiple SyS-T state context structures in parallel.
+ *
+ * @param header Pointer to SyS-T global state structure or NULL for default.
+ * @param pfinit Pointer to platform initialization function or 0 if not used.
+ * @param init_param Value passed to the the platform init hook function.
+ */
+MIPI_SYST_EXPORT void MIPI_SYST_CALLCONV
+mipi_syst_init(
+ struct mipi_syst_header* header,
+ mipi_syst_inithook_t pfinit,
+ const void *init_param)
+{
+ if (0 == header) {
+ /* No user supplied global state storage,
+ * use internal default state
+ */
+ header = &syst_hdr;
+ }
+
+ *header = zero.header;
+ header->systh_version = MIPI_SYST_VERSION_CODE;
+
+#if MIPI_SYST_CONFORMANCE_LEVEL > 10
+#if defined(MIPI_SYST_PCFG_ENABLE_DEFAULT_SCATTER_WRITE)
+ header->systh_writer = mipi_syst_scatter_write;
+#else
+ header->systh_writer = nullWriter;
+#endif
+#endif
+
+ /* call platform state initialization hook if defined
+ */
+ if ((mipi_syst_inithook_t) 0 != pfinit)
+ (*pfinit) (header, init_param);
+}
+
+/**
+ * Destroy the SyS-T library state.
+ *
+ * This function must be called during shutdown of the platform to release
+ * any SyS-T resources.
+ *
+ * @param header Pointer to library state or NULL to use shared default.
+ * @param pfdestroy Pointer to platform state destroy function or 0
+ * if not used.
+ */
+MIPI_SYST_EXPORT void MIPI_SYST_CALLCONV
+mipi_syst_destroy(struct mipi_syst_header* header, mipi_syst_destroyhook_t pfdestroy)
+{
+ if (0 == header) {
+ /* No user supplied global state storage,
+ * use internal default state
+ */
+ header = &syst_hdr;
+ }
+
+ /* call platform state destroy hook first, if defined
+ */
+ if ((mipi_syst_destroyhook_t) 0 != pfdestroy)
+ (*pfdestroy) (header);
+}
+
+/**
+ * Initialize a SyS-T handle.
+ *
+ * @param header Pointer to library state or NULL to use shared default.
+ * @param svh Pointer to new/uninitialized SyS-T handle
+ * @param origin Value passed to the the platform handle init function
+ * @param fromHeap 1 of heap allocated handle, 0 otherwise
+ */
+MIPI_SYST_EXPORT struct mipi_syst_handle* MIPI_SYST_CALLCONV
+mipi_syst_init_handle(
+ struct mipi_syst_header* header,
+ struct mipi_syst_handle* svh,
+ const struct mipi_syst_origin *origin,
+ mipi_syst_u32 fromHeap)
+{
+ if ((struct mipi_syst_handle*) 0 == svh)
+ return svh;
+
+
+ if (0 == header) {
+ /* No user supplied global state storage,
+ * use internal default state
+ */
+ header = &syst_hdr;
+ }
+
+ *svh = zero.handle;
+
+ svh->systh_header = header;
+ svh->systh_flags.shf_alloc = fromHeap ? 1 : 0;
+
+#if defined(MIPI_SYST_PCFG_ENABLE_ORIGIN_GUID)
+
+ if (0 != origin)
+ {
+ MIPI_SYST_SET_HANDLE_ORIGIN(svh, *origin);
+ }
+#endif
+
+ /* call platform handle initialization hook if defined
+ */
+#if defined(MIPI_SYST_PCFG_ENABLE_PLATFORM_HANDLE_DATA)
+ if ((mipi_syst_inithandle_hook_t) 0 != svh->systh_header->systh_inith)
+ svh->systh_header->systh_inith(svh);
+#endif
+ return svh;
+}
+
+/**
+ * Release a SyS-T handle.
+ *
+ * @param svh Pointer to initialized SyS-T handle
+ */
+MIPI_SYST_EXPORT void MIPI_SYST_CALLCONV mipi_syst_delete_handle(struct mipi_syst_handle* svh)
+{
+ if ((struct mipi_syst_handle*) 0 != svh) {
+#if defined(MIPI_SYST_PCFG_ENABLE_PLATFORM_HANDLE_DATA)
+ /* call platform handle release hook if defined
+ */
+ if ((mipi_syst_releasehandle_hook_t) 0 !=
+ svh->systh_header->systh_releaseh)
+ svh->systh_header->systh_releaseh(svh);
+#endif
+
+#if defined(MIPI_SYST_PCFG_ENABLE_HEAP_MEMORY)
+ if (0 != svh->systh_flags.shf_alloc) {
+ MIPI_SYST_HEAP_FREE(svh);
+ } else
+#endif
+ {
+ *svh = zero.handle;
+ }
+ }
+} \ No newline at end of file
diff --git a/library/src/mipi_syst_inline.c b/library/src/mipi_syst_inline.c
new file mode 100644
index 0000000..ca22ef0
--- /dev/null
+++ b/library/src/mipi_syst_inline.c
@@ -0,0 +1,48 @@
+/*
+Copyright (c) 2018, MIPI Alliance, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+* Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+* Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+ * Contributors:
+ * Norbert Schulz (Intel Corporation) - Initial API and implementation
+ */
+
+#include "mipi_syst.h"
+
+/* Include inline function in this cpp file if functions inline
+ * support is disabled by the platform define
+ * MIPI_SYST_PCFG_ENABLE_INLINE.
+ * Implementation will then use true functions to save code space.
+ */
+#if !defined(MIPI_SYST_PCFG_ENABLE_INLINE)
+#include "mipi_syst/inline.h"
+#endif \ No newline at end of file
diff --git a/library/src/mipi_syst_writer.c b/library/src/mipi_syst_writer.c
new file mode 100644
index 0000000..3120ff3
--- /dev/null
+++ b/library/src/mipi_syst_writer.c
@@ -0,0 +1,219 @@
+/*
+Copyright (c) 2018, MIPI Alliance, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+* Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+* Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+ * Contributors:
+ * Norbert Schulz (Intel Corporation) - Initial API and implementation
+ */
+#include "mipi_syst.h"
+#include "mipi_syst/message.h"
+#include "mipi_syst/crc32.h"
+
+#if defined(MIPI_SYST_PCFG_ENABLE_DEFAULT_SCATTER_WRITE)
+
+ /** scatter write routine
+ *
+ * This function implements the scatter write algorithm that translates
+ * the logical SyS-T memory descriptor representation into output
+ * requests. The actual output routines are defined through
+ * the MIPI_SYST_OUTPUT_* definitions from the platform header file.
+ *
+ * @param systh used syst handle
+ * @param scatterprog message content write instructions
+ * @param pdesc pointer to memory area with message data
+ */
+void mipi_syst_scatter_write(struct mipi_syst_handle* systh,
+ struct mipi_syst_scatter_prog *scatterprog, const void *pdesc)
+{
+ unsigned int repeat;
+
+ /* Define an "any" size integer pointer to avoid casts and to simplify
+ * type based incrementing
+ */
+ union {
+ const void *vp;
+ const mipi_syst_u8 *bp;
+ const mipi_syst_u16 *hp;
+ const mipi_syst_u32 *wp;
+ const mipi_syst_u64 *dp;
+ } data;
+
+#if defined(MIPI_SYST_PCFG_ENABLE_CHECKSUM)
+#define IFDO(a, b) { if (a) do { b; } while (0); }
+
+ mipi_syst_u32 crc;
+ int use_crc;
+
+ use_crc = systh->systh_tag.et_chksum;
+ crc = MIPI_SYST_CRC32_INIT(0);
+#else
+
+#define IFDO(a, b)
+ /* no checksump computation support */
+#endif
+
+ /* Write the "always" present tag field as a time-stamped D32 */
+ MIPI_SYST_OUTPUT_D32TS(systh, *(mipi_syst_u32 *)pdesc);
+
+ IFDO(use_crc, MIPI_SYST_CRC32_U32(crc, *(mipi_syst_u32 *)pdesc));
+
+ /* Run the message scatter write program to dump the message contents
+ */
+ while (scatterprog->sso_opcode != MIPI_SYST_SCATTER_OP_END) {
+ repeat = scatterprog->sso_length;
+ data.vp = pdesc;
+ data.bp += scatterprog->sso_offset;
+
+ switch (scatterprog->sso_opcode) {
+ case MIPI_SYST_SCATTER_OP_8BIT:
+ do {
+ MIPI_SYST_OUTPUT_D8(systh, *data.bp);
+ IFDO(use_crc,
+ MIPI_SYST_CRC32_U8(crc, *data.bp));
+ ++data.bp;
+ } while (--repeat);
+ break;
+
+ case MIPI_SYST_SCATTER_OP_16BIT:
+ do {
+ MIPI_SYST_OUTPUT_D16(systh, *data.hp);
+ IFDO(use_crc,
+ MIPI_SYST_CRC32_U16(crc, *data.hp));
+ ++data.hp;
+ } while (--repeat);
+ break;
+
+ case MIPI_SYST_SCATTER_OP_32BIT:
+ do {
+ MIPI_SYST_OUTPUT_D32(systh, *data.wp);
+ IFDO(use_crc,
+ MIPI_SYST_CRC32_U32(crc, *data.wp));
+ ++data.wp;
+ } while (--repeat);
+ break;
+
+
+ case MIPI_SYST_SCATTER_OP_64BIT:
+ do {
+#if defined(MIPI_SYST_PCFG_ENABLE_64BIT_IO)
+ MIPI_SYST_OUTPUT_D64(systh, *data.dp);
+#else
+#if defined(MIPI_SYST_BIG_ENDIAN)
+ MIPI_SYST_OUTPUT_D32(systh, data.wp[1]);
+ MIPI_SYST_OUTPUT_D32(systh, data.wp[0]);
+#else
+ MIPI_SYST_OUTPUT_D32(systh, data.wp[0]);
+ MIPI_SYST_OUTPUT_D32(systh, data.wp[1]);
+#endif
+
+#endif /* ! defined(MIPI_SYST_PCFG_ENABLE_64BIT_IO) */
+ IFDO(use_crc,
+ MIPI_SYST_CRC32_U64(crc, *data.dp));
+ ++data.dp;
+ } while (--repeat);
+ break;
+
+ case MIPI_SYST_SCATTER_OP_BLOB:
+ /* data location is pointer to real data,
+ * not data itself
+ */
+ data.vp = *(void **)data.vp;
+
+#if defined(MIPI_SYST_PCFG_ENABLE_64BIT_IO)
+
+ while (repeat >= sizeof(mipi_syst_u64)) {
+ mipi_syst_u64 v;
+ v = MIPI_SYST_HTOLE64(*data.dp);
+ MIPI_SYST_OUTPUT_D64(systh, v);
+ IFDO(use_crc,
+ MIPI_SYST_CRC32_U64(crc, v));
+ ++data.dp;
+ repeat -= sizeof(mipi_syst_u64);
+ }
+
+ if (repeat >= sizeof(mipi_syst_u32)) {
+ mipi_syst_u32 v;
+ v = MIPI_SYST_HTOLE32(*data.wp);
+ MIPI_SYST_OUTPUT_D32(systh, v);
+ IFDO(use_crc,
+ MIPI_SYST_CRC32_U32(crc,
+ *data.wp));
+ ++data.wp;
+ repeat -= sizeof(mipi_syst_u32);
+ }
+#else
+ while (repeat >= sizeof(mipi_syst_u32)) {
+ mipi_syst_u32 v;
+ v = MIPI_SYST_HTOLE32(*data.wp);
+ MIPI_SYST_OUTPUT_D32(systh, v);
+
+ IFDO(use_crc,
+ MIPI_SYST_CRC32_U32(crc, v));
+ ++data.wp;
+ repeat -= sizeof(mipi_syst_u32);
+ }
+#endif
+ if (repeat >= sizeof(mipi_syst_u16)) {
+ mipi_syst_u16 v;
+ v = MIPI_SYST_HTOLE16(*data.hp);
+ MIPI_SYST_OUTPUT_D16(systh, v);
+
+ IFDO(use_crc,
+ MIPI_SYST_CRC32_U16(crc, v));
+ ++data.hp;
+ repeat -= sizeof(mipi_syst_u16);
+ }
+
+ if (repeat) {
+ MIPI_SYST_OUTPUT_D8(systh,
+ *data.bp);
+ IFDO(use_crc,
+ MIPI_SYST_CRC32_U8(crc, *data.bp));
+ }
+ break;
+ }
+ ++scatterprog;
+ }
+
+#if defined(MIPI_SYST_PCFG_ENABLE_CHECKSUM)
+ if (use_crc) {
+ crc = MIPI_SYST_CRC32_GET(crc);
+ MIPI_SYST_OUTPUT_D32(systh, crc);
+ }
+#endif
+
+ /* EVENT end of record mark */
+ MIPI_SYST_OUTPUT_FLAG(systh);
+}
+
+#endif /* defined(MIPI_SYST_PCFG_ENABLE_DEFAULT_SCATTER_WRITE) */ \ No newline at end of file