aboutsummaryrefslogtreecommitdiff
path: root/library/src/mipi_syst_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'library/src/mipi_syst_api.c')
-rw-r--r--library/src/mipi_syst_api.c1314
1 files changed, 1314 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