summaryrefslogtreecommitdiffstats
path: root/import/chips/p9/common/pmlib/ppc405lib
diff options
context:
space:
mode:
authorYue Du <daviddu@us.ibm.com>2015-10-08 13:40:33 -0500
committerJoshua Hunsberger <jahunsbe@us.ibm.com>2017-10-23 15:56:18 -0500
commita1268463544386716f41f17da0e7e35ee9375343 (patch)
tree6ed1fd767335b79422c9605c1b5bc90e4af8330e /import/chips/p9/common/pmlib/ppc405lib
parent286b12fc048eae37ea3ac04ac4aba8778d02d2a4 (diff)
downloadtalos-hcode-a1268463544386716f41f17da0e7e35ee9375343.tar.gz
talos-hcode-a1268463544386716f41f17da0e7e35ee9375343.zip
first draft of ppe_closed/cme & sgpe, and common/pmlib/
Change-Id: I08440fadfeff7e4777a776167d4fdcffe5fec82f Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/21058 Tested-by: Jenkins Server Reviewed-by: Gregory S. Still <stillgs@us.ibm.com>
Diffstat (limited to 'import/chips/p9/common/pmlib/ppc405lib')
-rw-r--r--import/chips/p9/common/pmlib/ppc405lib/Makefile56
-rw-r--r--import/chips/p9/common/pmlib/ppc405lib/README.txt4
-rw-r--r--import/chips/p9/common/pmlib/ppc405lib/assert.c72
-rw-r--r--import/chips/p9/common/pmlib/ppc405lib/chip_config.h109
-rw-r--r--import/chips/p9/common/pmlib/ppc405lib/ctype.c42
-rw-r--r--import/chips/p9/common/pmlib/ppc405lib/ctype.h149
-rw-r--r--import/chips/p9/common/pmlib/ppc405lib/ctype_table.c303
-rw-r--r--import/chips/p9/common/pmlib/ppc405lib/errno.h49
-rw-r--r--import/chips/p9/common/pmlib/ppc405lib/fgetc.c122
-rw-r--r--import/chips/p9/common/pmlib/ppc405lib/libppc405files.mk74
-rw-r--r--import/chips/p9/common/pmlib/ppc405lib/libssx.h44
-rw-r--r--import/chips/p9/common/pmlib/ppc405lib/polling.c112
-rw-r--r--import/chips/p9/common/pmlib/ppc405lib/polling.h118
-rw-r--r--import/chips/p9/common/pmlib/ppc405lib/printf.c986
-rw-r--r--import/chips/p9/common/pmlib/ppc405lib/puts.c131
-rw-r--r--import/chips/p9/common/pmlib/ppc405lib/simics_stdio.c190
-rw-r--r--import/chips/p9/common/pmlib/ppc405lib/simics_stdio.h94
-rw-r--r--import/chips/p9/common/pmlib/ppc405lib/simics_stdio_addresses.h91
-rw-r--r--import/chips/p9/common/pmlib/ppc405lib/sprintf.c138
-rw-r--r--import/chips/p9/common/pmlib/ppc405lib/ssx_dump.c245
-rw-r--r--import/chips/p9/common/pmlib/ppc405lib/ssx_dump.h82
-rw-r--r--import/chips/p9/common/pmlib/ppc405lib/ssx_io.c363
-rw-r--r--import/chips/p9/common/pmlib/ppc405lib/ssx_io.h229
-rw-r--r--import/chips/p9/common/pmlib/ppc405lib/stdlib.c115
-rw-r--r--import/chips/p9/common/pmlib/ppc405lib/strcasecmp.c102
-rw-r--r--import/chips/p9/common/pmlib/ppc405lib/strdup.c66
-rw-r--r--import/chips/p9/common/pmlib/ppc405lib/string_stream.c477
-rw-r--r--import/chips/p9/common/pmlib/ppc405lib/string_stream.h278
-rw-r--r--import/chips/p9/common/pmlib/ppc405lib/strtox.c726
-rw-r--r--import/chips/p9/common/pmlib/ppc405lib/strtox.h151
-rw-r--r--import/chips/p9/common/pmlib/ppc405lib/time.c85
31 files changed, 5803 insertions, 0 deletions
diff --git a/import/chips/p9/common/pmlib/ppc405lib/Makefile b/import/chips/p9/common/pmlib/ppc405lib/Makefile
new file mode 100644
index 00000000..d6165113
--- /dev/null
+++ b/import/chips/p9/common/pmlib/ppc405lib/Makefile
@@ -0,0 +1,56 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: import/chips/p9/common/pmlib/ppc405lib/Makefile $
+#
+# OpenPOWER HCODE Project
+#
+# COPYRIGHT 2015,2017
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# This Makefile currently builds a single archive, 'libppc405.a', from
+# various library source files.
+#
+# part of the complete application build.
+#
+
+#all generated files from this makefile will end up in obj/$(IMAGE_NAME)/ppc405lib
+export SUB_OBJDIR = /ppc405lib
+
+include img_defs.mk
+include libppc405files.mk
+
+OBJS := $(addprefix $(OBJDIR)/, $(LIBPPC405_OBJECTS))
+
+libppc405.a: local
+ $(AR) crs $(OBJDIR)/libppc405.a $(OBJDIR)/*.o
+
+.PHONY: clean
+
+local: $(OBJS)
+
+$(OBJS) $(OBJS:.o=.d): | $(OBJDIR)
+
+$(OBJDIR):
+ mkdir -p $(OBJDIR)
+
+clean:
+ rm -fr $(OBJDIR)
+
+ifneq ($(MAKECMDGOALS),clean)
+#include $(OBJS:.o=.d)
+endif
diff --git a/import/chips/p9/common/pmlib/ppc405lib/README.txt b/import/chips/p9/common/pmlib/ppc405lib/README.txt
new file mode 100644
index 00000000..cc0076fc
--- /dev/null
+++ b/import/chips/p9/common/pmlib/ppc405lib/README.txt
@@ -0,0 +1,4 @@
+This directory contains all of the library code that only can run on the ppc405.
+For most of the files, the only reason it can not run on the ppe42 is because of
+it's dependence on SSX. Eventually, we would like to fix this so that most, if
+not all files can be made common.
diff --git a/import/chips/p9/common/pmlib/ppc405lib/assert.c b/import/chips/p9/common/pmlib/ppc405lib/assert.c
new file mode 100644
index 00000000..5c7a587e
--- /dev/null
+++ b/import/chips/p9/common/pmlib/ppc405lib/assert.c
@@ -0,0 +1,72 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/common/pmlib/ppc405lib/assert.c $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2015,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: assert.c,v 1.1.1.1 2013/12/11 20:49:20 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/assert.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file assert.c
+/// \brief Implementation of library routines implied by <assert.h>
+
+#include "ssx.h"
+#include "ssx_io.h"
+#include "libssx.h"
+
+/// The __assert_fail() function is used to implement the assert() interface
+/// of ISO POSIX (2003). The __assert_fail() function prints the given \a
+/// file filename, \a line line number, \a function function name and a
+/// message on the standard error stream then causes a kernel panic. If there
+/// is no standard error stream then the error message is printed on the \a
+/// ssxout (printk()) stream.
+///
+/// If function is NULL, __assert_fail() omits information about the
+/// function. The aguments \a assertion, \a file, and \a line must be
+/// non-NULL.
+
+void
+__assert_fail(const char* assertion,
+ const char* file,
+ unsigned line,
+ const char* function)
+{
+ FILE* stream;
+
+ stream = stderr;
+
+ if (stream == 0)
+ {
+ stream = ssxout;
+ }
+
+ fprintf(stream, "%s:%u:%s%s Assertion '%s' failed\n",
+ file, line,
+ function ? function : "", function ? ":" : "",
+ assertion);
+
+ SSX_PANIC(ASSERTION_FAILURE);
+}
diff --git a/import/chips/p9/common/pmlib/ppc405lib/chip_config.h b/import/chips/p9/common/pmlib/ppc405lib/chip_config.h
new file mode 100644
index 00000000..54e498fa
--- /dev/null
+++ b/import/chips/p9/common/pmlib/ppc405lib/chip_config.h
@@ -0,0 +1,109 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/common/pmlib/ppc405lib/chip_config.h $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2015,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __CHIP_CONFIG_H__
+#define __CHIP_CONFIG_H__
+
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file chip_config.h
+/// \brief Chip configuration data structures for OCC procedures
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+/// A bitmask defining a chip configuration
+///
+/// Since we are using the conventional big-endian notation, any use of these
+/// bitmasks requires that the data being tested is of this type - otherwise
+/// the masks won't work.
+///
+/// Layout:
+///
+/// Bits 0:15 - Core chiplet 0..15 is configured
+/// Bits 16:23 - MCS 0..7 is configured
+/// Bits 24:31 - Centaur 0..7 is configured
+
+typedef uint64_t ChipConfig;
+typedef uint16_t ChipConfigCores;
+typedef uint8_t ChipConfigMcs;
+typedef uint8_t ChipConfigCentaur;
+
+
+/// Convert a ChipConfig into a mask suitable for use as the 32-bit chiplet
+/// mask argument of a PORE wakeup program.
+#if 0
+static inline uint32_t
+pore_exe_mask(ChipConfig config)
+{
+ return (uint32_t)((config >> 32) & 0xffff0000);
+}
+#endif
+
+/// Left justify and mask core chiplet configuration into a uint32_t
+
+static inline uint32_t
+left_justify_core_config(ChipConfig config)
+{
+ return (uint32_t)((config >> 32) & 0xffff0000);
+}
+
+/// Left justify and mask MCS configuration into a uint32_t
+
+static inline uint32_t
+left_justify_mcs_config(ChipConfig config)
+{
+ return (uint32_t)((config >> 16) & 0xff000000);
+}
+
+/// Left justify and mask Centaur configuration into a uint32_t
+
+static inline uint32_t
+left_justify_centaur_config(ChipConfig config)
+{
+ return (uint32_t)((config >> 8) & 0xff000000);
+}
+
+#endif // __ASSEMBLER__
+
+
+#define CHIP_CONFIG_CORE_BASE 0
+#define CHIP_CONFIG_CORE(n) \
+ ((0x8000000000000000ull >> CHIP_CONFIG_CORE_BASE) >> (n))
+
+#define CHIP_CONFIG_MCS_BASE 16
+#define CHIP_CONFIG_MCS(n) \
+ ((0x8000000000000000ull >> CHIP_CONFIG_MCS_BASE) >> (n))
+
+#define CHIP_CONFIG_CENTAUR_BASE 24
+#define CHIP_CONFIG_CENTAUR(n) \
+ ((0x8000000000000000ull >> CHIP_CONFIG_CENTAUR_BASE) >> (n))
+
+
+#endif /* __CHIP_CONFIG_H__ */
diff --git a/import/chips/p9/common/pmlib/ppc405lib/ctype.c b/import/chips/p9/common/pmlib/ppc405lib/ctype.c
new file mode 100644
index 00000000..d570b49d
--- /dev/null
+++ b/import/chips/p9/common/pmlib/ppc405lib/ctype.c
@@ -0,0 +1,42 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/common/pmlib/ppc405lib/ctype.c $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2015,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: ctype.c,v 1.1.1.1 2013/12/11 20:49:20 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/ctype.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ctype.c
+/// \brief Replacement for <ctype.h> functions
+///
+/// This file contains entry point equivalents for the "ctype.h" macros.
+/// These would only ever be used by assembler programs, therefore it's likely
+/// that the object file will never be linked into an image.
+
+#define __CTYPE_C__
+#include "ctype.h"
+#undef __CTYPE_C__
diff --git a/import/chips/p9/common/pmlib/ppc405lib/ctype.h b/import/chips/p9/common/pmlib/ppc405lib/ctype.h
new file mode 100644
index 00000000..0e3fbece
--- /dev/null
+++ b/import/chips/p9/common/pmlib/ppc405lib/ctype.h
@@ -0,0 +1,149 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/common/pmlib/ppc405lib/ctype.h $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2015,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __CTYPE_H__
+#define __CTYPE_H__
+
+// $Id: ctype.h,v 1.1.1.1 2013/12/11 20:49:20 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/ctype.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ctype.h
+/// \brief Replacement for <ctype.h>
+///
+/// The Gnu <ctype.h> requires some locale information to be defined. We
+/// avoid this overhead and implement the simple functions, simply assuming
+/// standard 8-bit ASCII. The standard requires that these be defined as entry
+/// points, but may be defined as macros, therefore all macros defined by
+/// ctype.h are also be replicated in \c ctype.c
+
+// The reference for which characters are included in each set was:
+//
+// http://www.cplusplus.com/reference/clibrary/cctype/
+//
+// Note that no code was copied from the above or any other published
+// description of the ctype.h functionality.
+
+// To keep space to a minimum we encode the 8 common types directly into
+// an 8-bit mask. Other types take a little longer to compute.
+
+#define _CTYPE_CNTRL 0x01
+#define _CTYPE_SPACE 0x02
+#define _CTYPE_PRINT 0x04
+#define _CTYPE_PUNCT 0x08
+#define _CTYPE_UPPER 0x10
+#define _CTYPE_LOWER 0x20
+#define _CTYPE_DIGIT 0x40
+#define _CTYPE_XDIGIT 0x80
+
+#ifndef __ASSEMBLER__
+
+#include "stdint.h"
+
+/// \bug <ctype.h> can not include <stdio.h> to get the definition of
+/// EOF. This is because it causes conflicts withe the pore_inline* code which
+/// is portable (and ported) to Linux and PHYP. We need to go back through the
+/// way the includes are done in SSX and this library and fix this. We should
+/// have redefined <stdio.h> rather than creating a new "ssx_io.h"
+
+#define _CTYPE_EOF -1
+
+// Note that in all of the type macros, 'c' is an unsigned char.
+
+extern const uint8_t _ctype[256];
+
+#define _CTYPE_ISLOWER(c) (_ctype[c] & _CTYPE_LOWER)
+
+#define _CTYPE_ISUPPER(c) (_ctype[c] & _CTYPE_UPPER)
+
+#define _CTYPE_ISALPHA(c) (_CTYPE_ISUPPER(c) || _CTYPE_ISLOWER(c))
+
+#define _CTYPE_ISDIGIT(c) (_ctype[c] & _CTYPE_DIGIT)
+
+#define _CTYPE_ISALNUM(c) (_CTYPE_ISALPHA(c) || _CTYPE_ISDIGIT(c))
+
+#define _CTYPE_ISXDIGIT(c) (_ctype[c] & _CTYPE_XDIGIT)
+
+#define _CTYPE_ISCNTRL(c) (_ctype[c] & _CTYPE_CNTRL)
+
+#define _CTYPE_ISSPACE(c) (_ctype[c] & _CTYPE_SPACE)
+
+#define _CTYPE_ISPRINT(c) (_ctype[c] & _CTYPE_PRINT)
+
+#define _CTYPE_ISGRAPH(c) (_CTYPE_ISPRINT(c) && ((c) != 0x20))
+
+#define _CTYPE_ISPUNCT(c) (_ctype[c] & _CTYPE_PUNCT)
+
+#define _CTYPE_TOUPPER(c) (islower(c) ? ((c) + ('A' - 'a')) : (c))
+
+#define _CTYPE_TOLOWER(c) (isupper(c) ? ((c) - ('A' - 'a')) : (c))
+
+// When #include'ed into ctype.c, the non-inline forms of the functions are
+// created.
+//
+// Note that the specification requires that 'c' "must have the value of an
+// unsigned char or EOF". The specification also stipulates that "The values
+// returned are non-zero if the character c falls into the tested class, and a
+// zero value if not."
+
+#ifdef __CTYPE_C__
+ #define _CTYPE_EXTERN_INLINE
+#else
+ #define _CTYPE_EXTERN_INLINE extern inline
+#endif
+
+#define _CTYPE_PREDICATE(predicate, def) \
+ _CTYPE_EXTERN_INLINE int predicate(int c) { \
+ return ((c == _CTYPE_EOF) ? \
+ 0 : _CTYPE_##def((unsigned char)c)); \
+ }
+
+#define _CTYPE_FUNCTION(function, def) \
+ _CTYPE_EXTERN_INLINE int function(int c) { \
+ return ((c == _CTYPE_EOF) ? \
+ _CTYPE_EOF : _CTYPE_##def((unsigned char)c)); \
+ }
+
+_CTYPE_PREDICATE(islower, ISLOWER)
+_CTYPE_PREDICATE(isupper, ISUPPER)
+_CTYPE_PREDICATE(isalpha, ISALPHA)
+_CTYPE_PREDICATE(isdigit, ISDIGIT)
+_CTYPE_PREDICATE(isalnum, ISALNUM)
+_CTYPE_PREDICATE(isxdigit, ISXDIGIT)
+_CTYPE_PREDICATE(iscntrl, ISCNTRL)
+_CTYPE_PREDICATE(isspace, ISSPACE)
+_CTYPE_PREDICATE(isprint, ISPRINT)
+_CTYPE_PREDICATE(isgraph, ISGRAPH)
+_CTYPE_PREDICATE(ispunct, ISPUNCT)
+
+_CTYPE_FUNCTION(tolower, TOLOWER)
+_CTYPE_FUNCTION(toupper, TOUPPER)
+
+#endif // __ASSEMBLER__
+
+#endif /* __CTYPE_H__ */
diff --git a/import/chips/p9/common/pmlib/ppc405lib/ctype_table.c b/import/chips/p9/common/pmlib/ppc405lib/ctype_table.c
new file mode 100644
index 00000000..9b407585
--- /dev/null
+++ b/import/chips/p9/common/pmlib/ppc405lib/ctype_table.c
@@ -0,0 +1,303 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/common/pmlib/ppc405lib/ctype_table.c $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2015,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: ctype_table.c,v 1.1.1.1 2013/12/11 20:49:20 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/ctype_table.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ctype_table.c
+/// \brief Character table for <ctype.h> functions.
+///
+/// This table is used by the <ctype.h> functions for a quick lookup of
+/// character type information. Because the true functional forms of <ctype.h>
+/// functions are likely never required, but this file is always required, it
+/// is stored separately from ctype.c to (slightly) reduce code/data space
+/// requirements.
+
+#include <stdint.h>
+#include <ctype.h>
+
+const uint8_t _ctype[256] =
+{
+ _CTYPE_CNTRL, /* 0 00 NUL Null char */
+ _CTYPE_CNTRL, /* 1 01 SOH Start of Heading */
+ _CTYPE_CNTRL, /* 2 02 STX Start of Text */
+ _CTYPE_CNTRL, /* 3 03 ETX End of Text */
+ _CTYPE_CNTRL, /* 4 04 EOT End of Transmission */
+ _CTYPE_CNTRL, /* 5 05 ENQ Enquiry */
+ _CTYPE_CNTRL, /* 6 06 ACK Acknowledgment */
+ _CTYPE_CNTRL, /* 7 07 BEL Bell */
+ _CTYPE_CNTRL, /* 8 08 BS Back Space */
+ _CTYPE_CNTRL | _CTYPE_SPACE, /* 9 09 HT Horizontal Tab */
+ _CTYPE_CNTRL | _CTYPE_SPACE, /* 10 0A LF Line Feed */
+ _CTYPE_CNTRL | _CTYPE_SPACE, /* 11 0B VT Vertical Tab */
+ _CTYPE_CNTRL | _CTYPE_SPACE, /* 12 0C FF Form Feed */
+ _CTYPE_CNTRL | _CTYPE_SPACE, /* 13 0D CR Carriage Return */
+ _CTYPE_CNTRL, /* 14 0E SO Shift Out / X-On */
+ _CTYPE_CNTRL, /* 15 0F SI Shift In / X-Off */
+ 0, /* 16 10 DLE Data Line Escape */
+ 0, /* 17 11 DC1 Device Control 1 (oft. XON) */
+ 0, /* 18 12 DC2 Device Control 2 */
+ 0, /* 19 13 DC3 Device Control 3 (oft. XOFF) */
+ 0, /* 20 14 DC4 Device Control 4 */
+ 0, /* 21 15 NAK Negative Acknowledgement */
+ 0, /* 22 16 SYN Synchronous Idle */
+ 0, /* 23 17 ETB End of Transmit Block */
+ 0, /* 24 18 CAN Cancel */
+ 0, /* 25 19 EM End of Medium */
+ 0, /* 26 1A SUB Substitute */
+ 0, /* 27 1B ESC Escape */
+ 0, /* 28 1C FS File Separator */
+ 0, /* 29 1D GS Group Separator */
+ 0, /* 30 1E RS Record Separator */
+ 0, /* 31 1F US Unit Separator */
+ _CTYPE_PRINT | _CTYPE_SPACE, /* 32 20 Space */
+ _CTYPE_PRINT | _CTYPE_PUNCT, /* 33 21 ! Exclamation mark */
+ _CTYPE_PRINT | _CTYPE_PUNCT, /* 34 22 " Double quotes (or speech marks) */
+ _CTYPE_PRINT | _CTYPE_PUNCT, /* 35 23 # Number */
+ _CTYPE_PRINT | _CTYPE_PUNCT, /* 36 24 $ Dollar */
+ _CTYPE_PRINT | _CTYPE_PUNCT, /* 37 25 % Procenttecken */
+ _CTYPE_PRINT | _CTYPE_PUNCT, /* 38 26 & Ampersand */
+ _CTYPE_PRINT | _CTYPE_PUNCT, /* 39 27 ' Single quote */
+ _CTYPE_PRINT | _CTYPE_PUNCT, /* 40 28 ( Open parenthesis (or open bracket) */
+ _CTYPE_PRINT | _CTYPE_PUNCT, /* 41 29 ) Close parenthesis (or close bracket) */
+ _CTYPE_PRINT | _CTYPE_PUNCT, /* 42 2A * Asterisk */
+ _CTYPE_PRINT | _CTYPE_PUNCT, /* 43 2B + Plus */
+ _CTYPE_PRINT | _CTYPE_PUNCT, /* 44 2C , Comma */
+ _CTYPE_PRINT | _CTYPE_PUNCT, /* 45 2D - Hyphen */
+ _CTYPE_PRINT | _CTYPE_PUNCT, /* 46 2E . Period, dot or full stop */
+ _CTYPE_PRINT | _CTYPE_PUNCT, /* 47 2F / Slash or divide */
+ _CTYPE_PRINT | _CTYPE_DIGIT, /* 48 30 0 Zero */
+ _CTYPE_PRINT | _CTYPE_DIGIT, /* 49 31 1 One */
+ _CTYPE_PRINT | _CTYPE_DIGIT, /* 50 32 2 Two */
+ _CTYPE_PRINT | _CTYPE_DIGIT, /* 51 33 3 Three */
+ _CTYPE_PRINT | _CTYPE_DIGIT, /* 52 34 4 Four */
+ _CTYPE_PRINT | _CTYPE_DIGIT, /* 53 35 5 Five */
+ _CTYPE_PRINT | _CTYPE_DIGIT, /* 54 36 6 Six */
+ _CTYPE_PRINT | _CTYPE_DIGIT, /* 55 37 7 Seven */
+ _CTYPE_PRINT | _CTYPE_DIGIT, /* 56 38 8 Eight */
+ _CTYPE_PRINT | _CTYPE_DIGIT, /* 57 39 9 Nine */
+ _CTYPE_PRINT | _CTYPE_PUNCT, /* 58 3A : Colon */
+ _CTYPE_PRINT | _CTYPE_PUNCT, /* 59 3B ; Semicolon */
+ _CTYPE_PRINT | _CTYPE_PUNCT, /* 60 3C < Less than (or open angled bracket) */
+ _CTYPE_PRINT | _CTYPE_PUNCT, /* 61 3D = Equals */
+ _CTYPE_PRINT | _CTYPE_PUNCT, /* 62 3E > Greater than (or close angled bracket) */
+ _CTYPE_PRINT | _CTYPE_PUNCT, /* 63 3F ? Question mark */
+ _CTYPE_PRINT | _CTYPE_PUNCT, /* 64 40 @ At symbol */
+ _CTYPE_PRINT | _CTYPE_UPPER | _CTYPE_XDIGIT, /* 65 41 A Uppercase A */
+ _CTYPE_PRINT | _CTYPE_UPPER | _CTYPE_XDIGIT, /* 66 42 B Uppercase B */
+ _CTYPE_PRINT | _CTYPE_UPPER | _CTYPE_XDIGIT, /* 67 43 C Uppercase C */
+ _CTYPE_PRINT | _CTYPE_UPPER | _CTYPE_XDIGIT, /* 68 44 D Uppercase D */
+ _CTYPE_PRINT | _CTYPE_UPPER | _CTYPE_XDIGIT, /* 69 45 E Uppercase E */
+ _CTYPE_PRINT | _CTYPE_UPPER | _CTYPE_XDIGIT, /* 70 46 F Uppercase F */
+ _CTYPE_PRINT | _CTYPE_UPPER, /* 71 47 G Uppercase G */
+ _CTYPE_PRINT | _CTYPE_UPPER, /* 72 48 H Uppercase H */
+ _CTYPE_PRINT | _CTYPE_UPPER, /* 73 49 I Uppercase I */
+ _CTYPE_PRINT | _CTYPE_UPPER, /* 74 4A J Uppercase J */
+ _CTYPE_PRINT | _CTYPE_UPPER, /* 75 4B K Uppercase K */
+ _CTYPE_PRINT | _CTYPE_UPPER, /* 76 4C L Uppercase L */
+ _CTYPE_PRINT | _CTYPE_UPPER, /* 77 4D M Uppercase M */
+ _CTYPE_PRINT | _CTYPE_UPPER, /* 78 4E N Uppercase N */
+ _CTYPE_PRINT | _CTYPE_UPPER, /* 79 4F O Uppercase O */
+ _CTYPE_PRINT | _CTYPE_UPPER, /* 80 50 P Uppercase P */
+ _CTYPE_PRINT | _CTYPE_UPPER, /* 81 51 Q Uppercase Q */
+ _CTYPE_PRINT | _CTYPE_UPPER, /* 82 52 R Uppercase R */
+ _CTYPE_PRINT | _CTYPE_UPPER, /* 83 53 S Uppercase S */
+ _CTYPE_PRINT | _CTYPE_UPPER, /* 84 54 T Uppercase T */
+ _CTYPE_PRINT | _CTYPE_UPPER, /* 85 55 U Uppercase U */
+ _CTYPE_PRINT | _CTYPE_UPPER, /* 86 56 V Uppercase V */
+ _CTYPE_PRINT | _CTYPE_UPPER, /* 87 57 W Uppercase W */
+ _CTYPE_PRINT | _CTYPE_UPPER, /* 88 58 X Uppercase X */
+ _CTYPE_PRINT | _CTYPE_UPPER, /* 89 59 Y Uppercase Y */
+ _CTYPE_PRINT | _CTYPE_UPPER, /* 90 5A Z Uppercase Z */
+ _CTYPE_PRINT | _CTYPE_PUNCT, /* 91 5B [ Opening bracket */
+ _CTYPE_PRINT | _CTYPE_PUNCT, /* 92 5C \ Backslash */
+ _CTYPE_PRINT | _CTYPE_PUNCT, /* 93 5D ] Closing bracket */
+ _CTYPE_PRINT | _CTYPE_PUNCT, /* 94 5E ^ Caret - circumflex */
+ _CTYPE_PRINT | _CTYPE_PUNCT, /* 95 5F _ Underscore */
+ _CTYPE_PRINT | _CTYPE_PUNCT, /* 96 60 ` Grave accent */
+ _CTYPE_PRINT | _CTYPE_LOWER | _CTYPE_XDIGIT, /* 97 61 a Lowercase a */
+ _CTYPE_PRINT | _CTYPE_LOWER | _CTYPE_XDIGIT, /* 98 62 b Lowercase b */
+ _CTYPE_PRINT | _CTYPE_LOWER | _CTYPE_XDIGIT, /* 99 63 c Lowercase c */
+ _CTYPE_PRINT | _CTYPE_LOWER | _CTYPE_XDIGIT, /* 100 64 d Lowercase d */
+ _CTYPE_PRINT | _CTYPE_LOWER | _CTYPE_XDIGIT, /* 101 65 e Lowercase e */
+ _CTYPE_PRINT | _CTYPE_LOWER | _CTYPE_XDIGIT, /* 102 66 f Lowercase f */
+ _CTYPE_PRINT | _CTYPE_LOWER, /* 103 67 g Lowercase g */
+ _CTYPE_PRINT | _CTYPE_LOWER, /* 104 68 h Lowercase h */
+ _CTYPE_PRINT | _CTYPE_LOWER, /* 105 69 i Lowercase i */
+ _CTYPE_PRINT | _CTYPE_LOWER, /* 106 6A j Lowercase j */
+ _CTYPE_PRINT | _CTYPE_LOWER, /* 107 6B k Lowercase k */
+ _CTYPE_PRINT | _CTYPE_LOWER, /* 108 6C l Lowercase l */
+ _CTYPE_PRINT | _CTYPE_LOWER, /* 109 6D m Lowercase m */
+ _CTYPE_PRINT | _CTYPE_LOWER, /* 110 6E n Lowercase n */
+ _CTYPE_PRINT | _CTYPE_LOWER, /* 111 6F o Lowercase o */
+ _CTYPE_PRINT | _CTYPE_LOWER, /* 112 70 p Lowercase p */
+ _CTYPE_PRINT | _CTYPE_LOWER, /* 113 71 q Lowercase q */
+ _CTYPE_PRINT | _CTYPE_LOWER, /* 114 72 r Lowercase r */
+ _CTYPE_PRINT | _CTYPE_LOWER, /* 115 73 s Lowercase s */
+ _CTYPE_PRINT | _CTYPE_LOWER, /* 116 74 t Lowercase t */
+ _CTYPE_PRINT | _CTYPE_LOWER, /* 117 75 u Lowercase u */
+ _CTYPE_PRINT | _CTYPE_LOWER, /* 118 76 v Lowercase v */
+ _CTYPE_PRINT | _CTYPE_LOWER, /* 119 77 w Lowercase w */
+ _CTYPE_PRINT | _CTYPE_LOWER, /* 120 78 x Lowercase x */
+ _CTYPE_PRINT | _CTYPE_LOWER, /* 121 79 y Lowercase y */
+ _CTYPE_PRINT | _CTYPE_LOWER, /* 122 7A z Lowercase z */
+ _CTYPE_PRINT | _CTYPE_PUNCT, /* 123 7B { Opening brace */
+ _CTYPE_PRINT | _CTYPE_PUNCT, /* 124 7C | Vertical bar */
+ _CTYPE_PRINT | _CTYPE_PUNCT, /* 125 7D } Closing brace */
+ _CTYPE_PRINT | _CTYPE_PUNCT, /* 126 7E ~ Equivalency sign - tilde */
+ 0, /* 127 7F Delete */
+ 0, /* 128 80 Euro sign */
+ 0, /* 129 81 */
+ 0, /* 130 82 ' Single low-9 quotation mark */
+ 0, /* 131 83 Latin small letter f with hook */
+ 0, /* 132 84 " Double low-9 quotation mark */
+ 0, /* 133 85 Horizontal ellipsis */
+ 0, /* 134 86 Dagger */
+ 0, /* 135 87 Double dagger */
+ 0, /* 136 88 Modifier letter circumflex accent */
+ 0, /* 137 89 Per mille sign */
+ 0, /* 138 8A Latin capital letter S with caron */
+ 0, /* 139 8B Single left-pointing angle quotation */
+ 0, /* 140 8C Latin capital ligature OE */
+ 0, /* 141 8D */
+ 0, /* 142 8E Latin captial letter Z with caron */
+ 0, /* 143 8F */
+ 0, /* 144 90 */
+ 0, /* 145 91 ' Left single quotation mark */
+ 0, /* 146 92 ' Right single quotation mark */
+ 0, /* 147 93 " Left double quotation mark */
+ 0, /* 148 94 " Right double quotation mark */
+ 0, /* 149 95 Bullet */
+ 0, /* 150 96 En dash */
+ 0, /* 151 97 Em dash */
+ 0, /* 152 98 Small tilde */
+ 0, /* 153 99 Trade mark sign */
+ 0, /* 154 9A Latin small letter S with caron */
+ 0, /* 155 9B Single right-pointing angle quotation mark */
+ 0, /* 156 9C Latin small ligature oe */
+ 0, /* 157 9D */
+ 0, /* 158 9E Latin small letter z with caron */
+ 0, /* 159 9F Latin capital letter Y with diaeresis */
+ 0, /* 160 A0 Non-breaking space */
+ 0, /* 161 A1 Inverted exclamation mark */
+ 0, /* 162 A2 Cent sign */
+ 0, /* 163 A3 Pound sign */
+ 0, /* 164 A4 Currency sign */
+ 0, /* 165 A5 Yen sign */
+ 0, /* 166 A6 Pipe, Broken vertical bar */
+ 0, /* 167 A7 Section sign */
+ 0, /* 168 A8 Spacing diaeresis - umlaut */
+ 0, /* 169 A9 Copyright sign */
+ 0, /* 170 AA Feminine ordinal indicator */
+ 0, /* 171 AB Left double angle quotes */
+ 0, /* 172 AC Not sign */
+ 0, /* 173 AD Soft hyphen */
+ 0, /* 174 AE Registered trade mark sign */
+ 0, /* 175 AF Spacing macron - overline */
+ 0, /* 176 B0 Degree sign */
+ 0, /* 177 B1 Plus-or-minus sign */
+ 0, /* 178 B2 Superscript two - squared */
+ 0, /* 179 B3 Superscript three - cubed */
+ 0, /* 180 B4 Acute accent - spacing acute */
+ 0, /* 181 B5 Micro sign */
+ 0, /* 182 B6 Pilcrow sign - paragraph sign */
+ 0, /* 183 B7 Middle dot - Georgian comma */
+ 0, /* 184 B8 Spacing cedilla */
+ 0, /* 185 B9 Superscript one */
+ 0, /* 186 BA Masculine ordinal indicator */
+ 0, /* 187 BB Right double angle quotes */
+ 0, /* 188 BC one quarter */
+ 0, /* 189 BD Fraction one half */
+ 0, /* 190 BE Fraction three quarters */
+ 0, /* 191 BF Inverted question mark */
+ 0, /* 192 C0 Latin capital letter A with grave */
+ 0, /* 193 C1 Latin capital letter A with acute */
+ 0, /* 194 C2 Latin capital letter A with circumflex */
+ 0, /* 195 C3 Latin capital letter A with tilde */
+ 0, /* 196 C4 Latin capital letter A with diaeresis */
+ 0, /* 197 C5 Latin capital letter A with ring above */
+ 0, /* 198 C6 Latin capital letter AE */
+ 0, /* 199 C7 Latin capital letter C with cedilla */
+ 0, /* 200 C8 Latin capital letter E with grave */
+ 0, /* 201 C9 Latin capital letter E with acute */
+ 0, /* 202 CA Latin capital letter E with circumflex */
+ 0, /* 203 CB Latin capital letter E with diaeresis */
+ 0, /* 204 CC Latin capital letter I with grave */
+ 0, /* 205 CD Latin capital letter I with acute */
+ 0, /* 206 CE Latin capital letter I with circumflex */
+ 0, /* 207 CF Latin capital letter I with diaeresis */
+ 0, /* 208 D0 Latin capital letter ETH */
+ 0, /* 209 D1 Latin capital letter N with tilde */
+ 0, /* 210 D2 Latin capital letter O with grave */
+ 0, /* 211 D3 Latin capital letter O with acute */
+ 0, /* 212 D4 Latin capital letter O with circumflex */
+ 0, /* 213 D5 Latin capital letter O with tilde */
+ 0, /* 214 D6 Latin capital letter O with diaeresis */
+ 0, /* 215 D7 Multiplication sign */
+ 0, /* 216 D8 Latin capital letter O with slash */
+ 0, /* 217 D9 Latin capital letter U with grave */
+ 0, /* 218 DA Latin capital letter U with acute */
+ 0, /* 219 DB Latin capital letter U with circumflex */
+ 0, /* 220 DC Latin capital letter U with diaeresis */
+ 0, /* 221 DD Latin capital letter Y with acute */
+ 0, /* 222 DE Latin capital letter THORN */
+ 0, /* 223 DF Latin small letter sharp s - ess-zed */
+ 0, /* 224 E0 Latin small letter a with grave */
+ 0, /* 225 E1 Latin small letter a with acute */
+ 0, /* 226 E2 Latin small letter a with circumflex */
+ 0, /* 227 E3 Latin small letter a with tilde */
+ 0, /* 228 E4 Latin small letter a with diaeresis */
+ 0, /* 229 E5 Latin small letter a with ring above */
+ 0, /* 230 E6 Latin small letter ae */
+ 0, /* 231 E7 Latin small letter c with cedilla */
+ 0, /* 232 E8 Latin small letter e with grave */
+ 0, /* 233 E9 Latin small letter e with acute */
+ 0, /* 234 EA Latin small letter e with circumflex */
+ 0, /* 235 EB Latin small letter e with diaeresis */
+ 0, /* 236 EC Latin small letter i with grave */
+ 0, /* 237 ED Latin small letter i with acute */
+ 0, /* 238 EE Latin small letter i with circumflex */
+ 0, /* 239 EF Latin small letter i with diaeresis */
+ 0, /* 240 F0 Latin small letter eth */
+ 0, /* 241 F1 Latin small letter n with tilde */
+ 0, /* 242 F2 Latin small letter o with grave */
+ 0, /* 243 F3 Latin small letter o with acute */
+ 0, /* 244 F4 Latin small letter o with circumflex */
+ 0, /* 245 F5 Latin small letter o with tilde */
+ 0, /* 246 F6 Latin small letter o with diaeresis */
+ 0, /* 247 F7 Division sign */
+ 0, /* 248 F8 Latin small letter o with slash */
+ 0, /* 249 F9 Latin small letter u with grave */
+ 0, /* 250 FA Latin small letter u with acute */
+ 0, /* 251 FB Latin small letter u with circumflex */
+ 0, /* 252 FC Latin small letter u with diaeresis */
+ 0, /* 253 FD Latin small letter y with acute */
+ 0, /* 254 FE Latin small letter thorn */
+ 0, /* 255 FF Latin small letter y with diaeresis */
+};
diff --git a/import/chips/p9/common/pmlib/ppc405lib/errno.h b/import/chips/p9/common/pmlib/ppc405lib/errno.h
new file mode 100644
index 00000000..8a2303ee
--- /dev/null
+++ b/import/chips/p9/common/pmlib/ppc405lib/errno.h
@@ -0,0 +1,49 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/common/pmlib/ppc405lib/errno.h $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2015,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __ERRNO_H__
+#define __ERRNO_H__
+
+// $Id: errno.h,v 1.1.1.1 2013/12/11 20:49:20 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/errno.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file errno.h
+/// \brief Replacement for <errno.h>
+///
+/// SSX does not support a per-thread or global 'errno'. The standard Unix
+/// errno values returned by library functions are defined here. The prefix
+/// code is the 'telephone code' for "errn".
+
+#define EINVAL 0x00377601
+#define EBADF 0x00377602
+#define EAGAIN 0x00377603
+#define ENXIO 0x00377604
+#define ENOMEM 0x00377605
+
+#endif /* __ERRNO_H__ */
diff --git a/import/chips/p9/common/pmlib/ppc405lib/fgetc.c b/import/chips/p9/common/pmlib/ppc405lib/fgetc.c
new file mode 100644
index 00000000..a5f543a1
--- /dev/null
+++ b/import/chips/p9/common/pmlib/ppc405lib/fgetc.c
@@ -0,0 +1,122 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/common/pmlib/ppc405lib/fgetc.c $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2015,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: fgetc.c,v 1.1.1.1 2013/12/11 20:49:20 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/fgetc.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file fgetc.c
+/// \brief Implementation of fgetc() and ungetc()
+///
+/// The implementations of these APIs are split out to save code space for
+/// applications that do not require them.
+
+#include "ssx_io.h"
+
+
+/// Read a character from a stream
+///
+/// fgetc() reads the next character from \a stream and returns it as an
+/// unsigned char cast to an int, or EOF on end of file or error.
+
+int
+fgetc(FILE* stream)
+{
+ unsigned char c;
+ size_t read;
+ int rc;
+
+ if (stream->flags & SSX_FILE_HAS_CHARACTER)
+ {
+ stream->flags &= ~SSX_FILE_HAS_CHARACTER;
+ rc = stream->character;
+ }
+ else
+ {
+ rc = sread(stream, &c, 1, &read);
+
+ if (rc || (read != 1))
+ {
+ rc = EOF;
+ }
+ else
+ {
+ rc = c;
+
+ if (c == '\n')
+ {
+ stream->lines++;
+ }
+ }
+ }
+
+ return rc;
+}
+
+
+/// Push a character back onto a stream
+///
+/// ungetc() pushes \a c back to \a stream, cast to unsigned char, where it is
+/// available for subsequent fgetc() operations. Only one pushback is
+/// implemented. A call of ungetc() on a stream that already has a character
+/// pushed back will drop the new push-back and return EOF. Otherwise
+/// ungetc() returns \a c.
+
+int
+ungetc(int c, FILE* stream)
+{
+ int rc;
+
+ if (stream->flags & SSX_FILE_HAS_CHARACTER)
+ {
+ rc = EOF;
+ }
+ else
+ {
+ stream->flags |= SSX_FILE_HAS_CHARACTER;
+ stream->character = c;
+ rc = c;
+ }
+
+ return rc;
+}
+
+/// Return the number of newline characters read from a stream
+///
+/// This API is an SSX entension to the \<stdio\> APIs. It returns the number
+/// of newline characters read from the stream using fgetc(). Newline
+/// characters read via direct calls to sread() in the stream are not counted.
+///
+/// An application that sees an error while reading from a stream can print
+/// flines() or flines() + 1 (depending on the application) to help users
+/// track down errors in their input.
+size_t
+flines(FILE* stream)
+{
+ return stream->lines;
+}
diff --git a/import/chips/p9/common/pmlib/ppc405lib/libppc405files.mk b/import/chips/p9/common/pmlib/ppc405lib/libppc405files.mk
new file mode 100644
index 00000000..ec672607
--- /dev/null
+++ b/import/chips/p9/common/pmlib/ppc405lib/libppc405files.mk
@@ -0,0 +1,74 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: import/chips/p9/common/pmlib/ppc405lib/libppc405files.mk $
+#
+# OpenPOWER HCODE Project
+#
+# COPYRIGHT 2015,2017
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# @file libppc405files.mk
+#
+# @brief mk for libppc405.a object files
+#
+# @page ChangeLogs Change Logs
+# @section libppc405files.mk
+# @verbatim
+#
+#
+# Change Log ******************************************************************
+# Flag Defect/Feature User Date Description
+# ------ -------------- ---------- ------------ -----------
+#
+# @endverbatim
+#
+##########################################################################
+# INCLUDES
+##########################################################################
+
+C-SOURCES = \
+ assert.c \
+ byte_pool.c \
+ ctype.c \
+ ctype_table.c \
+ fgetc.c \
+ initcall.c \
+ lfsr.c \
+ mutex.c \
+ periodic_semaphore.c \
+ polling.c \
+ printf.c \
+ progress.c \
+ puts.c \
+ rtx_stdio.c \
+ simics_stdio.c \
+ sprintf.c \
+ ssx_dump.c \
+ ssx_io.c \
+ stdlib.c \
+ strcasecmp.c \
+ strdup.c \
+ string.c \
+ string_stream.c \
+ strtox.c \
+ sxlock.c \
+ time.c
+
+S-SOURCES =
+
+LIBPPC405_OBJECTS = $(C-SOURCES:.c=.o) $(S-SOURCES:.S=.o)
diff --git a/import/chips/p9/common/pmlib/ppc405lib/libssx.h b/import/chips/p9/common/pmlib/ppc405lib/libssx.h
new file mode 100644
index 00000000..3938c5f1
--- /dev/null
+++ b/import/chips/p9/common/pmlib/ppc405lib/libssx.h
@@ -0,0 +1,44 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/common/pmlib/ppc405lib/libssx.h $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2015,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __LIBSSX_H__
+#define __LIBSSX_H__
+
+// $Id: libssx.h,v 1.1.1.1 2013/12/11 20:49:20 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/libssx.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file libssx.h
+/// \brief Header definitions with no other obvious home
+
+// Kernel panics
+
+#define ASSERTION_FAILURE 0x00542701
+#define ERROR_EXIT 0x00542702
+
+#endif // __LIBSSX_H__
diff --git a/import/chips/p9/common/pmlib/ppc405lib/polling.c b/import/chips/p9/common/pmlib/ppc405lib/polling.c
new file mode 100644
index 00000000..283a784a
--- /dev/null
+++ b/import/chips/p9/common/pmlib/ppc405lib/polling.c
@@ -0,0 +1,112 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/common/pmlib/ppc405lib/polling.c $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2015,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: polling.c,v 1.1.1.1 2013/12/11 20:49:20 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/polling.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file polling.c
+/// \brief Library APIs for polling
+
+#include "polling.h"
+
+int
+polling(int* o_rc,
+ int (*i_condition)(void* io_arg, int* o_satisfied),
+ void* io_arg,
+ SsxInterval i_timeout,
+ SsxInterval i_sleep)
+{
+ SsxTimebase start;
+ int rc, pollRc, timed_out, done;
+
+ if (SSX_ERROR_CHECK_API)
+ {
+ SSX_ERROR_IF((i_condition == 0), POLLING_ERROR);
+ }
+
+ start = ssx_timebase_get();
+ timed_out = 0;
+
+ do
+ {
+ pollRc = i_condition(io_arg, &done);
+
+ if (pollRc)
+ {
+ rc = POLLING_CONDITION;
+ break;
+ }
+
+ if (done)
+ {
+ rc = 0;
+ break;
+ }
+
+ if (timed_out)
+ {
+ rc = POLLING_TIMEOUT;
+ break;
+ }
+
+ if (i_sleep != 0)
+ {
+ rc = ssx_sleep(i_sleep);
+
+ if (rc)
+ {
+ break;
+ }
+ }
+
+ timed_out =
+ ((i_timeout != SSX_WAIT_FOREVER) &&
+ ((ssx_timebase_get() - start) >= i_timeout));
+
+ }
+ while (1);
+
+ if (o_rc)
+ {
+ *o_rc = pollRc;
+ }
+
+ return rc;
+}
+
+
+void
+busy_wait(SsxInterval i_interval)
+{
+ SsxTimebase start;
+
+ start = ssx_timebase_get();
+
+ while ((ssx_timebase_get() - start) < i_interval);
+}
diff --git a/import/chips/p9/common/pmlib/ppc405lib/polling.h b/import/chips/p9/common/pmlib/ppc405lib/polling.h
new file mode 100644
index 00000000..0cdb266c
--- /dev/null
+++ b/import/chips/p9/common/pmlib/ppc405lib/polling.h
@@ -0,0 +1,118 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/common/pmlib/ppc405lib/polling.h $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2015,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __POLLING_H__
+#define __POLLING_H__
+
+// $Id: polling.h,v 1.1.1.1 2013/12/11 20:49:20 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/polling.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file polling.c
+/// \brief Library APIs for polling and busy-waiting
+
+#include "ssx.h"
+
+// Return/Panic codes
+
+#define POLLING_TIMEOUT 0x00765501
+#define POLLING_ERROR 0x00765502
+#define POLLING_CONDITION 0x00765503
+
+
+#ifndef __ASSEMBLER__
+
+/// Poll for a condition or a timeout with optional sleep
+///
+/// \param[out] o_rc The last return code from calling \a i_condition. This
+/// will only be valid if the return code from polling() is
+/// POLLING_CONDITION. This argument may be passed as NULL (0) if the caller
+/// does not require this information.
+///
+/// \param[in] i_condition A function of two arguments, returning an integer
+/// return code - 0 for success, non-0 for failure. The first argument is a
+/// private state or parameter variable. The second argument is used to
+/// return the truth value of the \a i_condition predicate (0 for false, non-0
+/// for true), and is only considered if the return value of \a i_condition is
+/// 0.
+///
+/// \param[in,out] io_arg The private argument of the \a condition function.
+///
+/// \param[in] i_timeout The maximum amount of time to poll the \a condition
+/// before declaring a timeout. The special value SSX_WAIT_FOREVER can be
+/// used to specify polling without timeout.
+///
+/// \param[in] i_sleep If non-0 at entry, then the thread will sleep for this
+/// interval between polls of the condition. Otherwise the polling is
+/// continuous. polling() can only be called with i_sleep non-0 from a
+/// thread context (since interrupt contexts can not block).
+///
+/// polling() implements a generic polling protocol for conditions that can
+/// not be recognized as interrupt events. polling() polls the \a i_condition
+/// until either an error is encountered, the condition is true, or the
+/// polling times out as measured by the SSX timebase. Whenever a timeout is
+/// detected the condition is polled once more to exclude false timeouts that
+/// may have been caused by thread preemption.
+///
+/// The \a i_sleep A non-0 value of \a i_sleep specifies that the thread
+/// should sleep for the given interval between polling tries instead of
+/// polling continuously. A non-0 \a i_sleep argument is only legal in thread
+/// contexts.
+///
+/// \retval 0 Success; The condition was satisfied prior to the timeout.
+///
+/// \retval POLLING_TIMEOUT A timeout was detected before the condition became
+/// valid.
+///
+/// \retval POLLING_ERROR This code is returned if any of the arguments of
+/// polling() are invalid.
+///
+/// \retval POLLING_CONDITION This code is returned if the \a i_condition
+/// function returns a non-0 return code.
+///
+/// If the embedded call of ssx_sleep() fails for some reason then the return
+/// code will be the code returned by ssx_sleep().
+int
+polling(int* o_rc,
+ int (*i_condition)(void* io_arg, int* o_satisfied),
+ void* io_arg,
+ SsxInterval i_timeout,
+ SsxInterval i_sleep);
+
+
+/// A busy-wait loop
+///
+/// \param[in] i_interval The interval of time to busy-wait. The actual
+/// interval may be more than this if the thread is interrupted. If called
+/// from a context with interrupts disabled the timing should be very precise.
+void
+busy_wait(SsxInterval i_interval);
+
+#endif // __ASSEMBLER__
+
+#endif // __POLLING_H__
diff --git a/import/chips/p9/common/pmlib/ppc405lib/printf.c b/import/chips/p9/common/pmlib/ppc405lib/printf.c
new file mode 100644
index 00000000..ea895de3
--- /dev/null
+++ b/import/chips/p9/common/pmlib/ppc405lib/printf.c
@@ -0,0 +1,986 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/common/pmlib/ppc405lib/printf.c $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2015,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: printf.c,v 1.1.1.1 2013/12/11 20:49:20 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/printf.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file printf.c
+/// \brief Clean-room implementation of printf() functions for SSX I/O
+///
+/// For licensing reasons we are required to create our own version of the
+/// printf() family of functions. This implementation was created without
+/// reference to or inclusion of any licensed or copyrighted code.
+///
+/// The functions defined in this file have prototypes, behavior and return
+/// values as defined by C language standards. In the event of an error a
+/// negative value is returned, generally corresponding to a standard Unix
+/// 'errno' code. Note that SSX does not support either an application- or
+/// per-thread 'errno', so the only record of any error is the \a error field
+/// of the stream. Also note that SSX may be configured to cause a panic if an
+/// error is detected rather than returning an error code.
+///
+/// This implementation defines a limited but useful subset of the C standard
+/// for format control. This implementation includes the following:
+///
+/// - \b c, \b d, \b i, \b n, \b p, \b s, \b u, \b x, and \b X conversion
+/// specifiers, as well as '%%' to output a single '%'
+///
+/// - \b #, \b 0, \b ' ' and \b + flag characters
+///
+/// - Decimal field width specifiers including * (but indirect field widths
+/// must be positive as left-justification is not supported)
+///
+/// - Decimal precision specifiers (currently only apply to %s formats, may be
+/// indirect using *)
+///
+/// - \b l, \b ll and \b z length modifiers
+///
+/// \b Notes:
+///
+/// \a If a \c p conversion specifier is used without any flags (\c '%p'), the
+/// \c p conversion is interptered as if it were \c 0x%08lx for 32-bit address
+/// machines and \c 0x%016llx for 64-bit address machines. The GCC builtin
+/// format checker gives warnings about '0' flag characters for \c p
+/// conversion specifiers, so there is otherwise no 'un-warned' way to get
+/// this preferred (by some) format of pointer values. If you do include
+/// explicit flags (e.g., \c %30p) they will be processed as expected.
+///
+/// Similar to how printf() behaves on an X86-Linux machine, a null pointer
+/// will print as "(null)" with the %s format (unless the precision specifier
+/// precludes it) and "(nil)" with the %p format.
+///
+/// Note that calling formatted I/O functions on non-blocking streams may fail
+/// with the -EAGAIN error, and there is no clean way to restart these
+/// calls. Calling formatted (or any) I/O functions on blocking streams from
+/// interrupt contexts in SSX is also likely to fail intermittently since
+/// interrupt contexts can not block in SSX.
+///
+/// \todo I'd really like to implement the '-' flag for
+/// left-justification. Implementing the precision specifer for integers
+/// should be done for completeness.
+
+#include "ssx.h"
+#include "ssx_io.h"
+
+// Formatting options
+
+#define OPTION_ALTERNATE 0x0001
+#define OPTION_PAD_ZERO 0x0002
+#define OPTION_PLUS_SIGN 0x0004
+#define OPTION_FIELD_WIDTH 0x0008
+#define OPTION_PRECISION 0x0010
+#define OPTION_LONG 0x0020
+#define OPTION_LONG_LONG 0x0040
+#define OPTION_SIZE_T 0x0080
+#define OPTION_UPPERCASE 0x0100
+#define OPTION_HEX 0x0200
+#define OPTION_SPACE 0x0400
+
+
+// Generate padding if required, returning the total number of pad characters
+// output or a negative error code. The 'nchars' argument is the number of
+// non-pad characters to be output by the caller.
+
+#define PAD_SIZE 8
+static const char zeros[PAD_SIZE] = {'0', '0', '0', '0', '0', '0', '0', '0'};
+static const char blanks[PAD_SIZE] = {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '};
+
+static ssize_t
+pad(FILE* stream, size_t nchars, int options, size_t width)
+{
+ const char* padchars;
+ size_t chars, written;
+ int rc;
+
+ if (!(options & OPTION_FIELD_WIDTH) || (nchars >= width))
+ {
+ return 0;
+ }
+
+ chars = width - nchars;
+
+ if (options & OPTION_PAD_ZERO)
+ {
+ padchars = zeros;
+ }
+ else
+ {
+ padchars = blanks;
+ }
+
+ while (chars)
+ {
+ rc = swrite(stream, (void*)padchars, MIN(chars, PAD_SIZE), &written);
+
+ if (rc < 0)
+ {
+ return rc;
+ }
+
+ chars -= written;
+ }
+
+ return width - nchars;
+}
+
+
+// Format a character
+
+static ssize_t
+format_char(FILE* stream, unsigned char c, int options, size_t width)
+{
+ ssize_t padchars, nchars;
+ int rc;
+
+ padchars = pad(stream, 1, options, width);
+
+ if (padchars < 0)
+ {
+ return padchars;
+ }
+
+ nchars = padchars + 1;
+ rc = swrite(stream, (void*)(&c), 1, 0);
+
+ if (rc < 0)
+ {
+ return rc;
+ }
+
+ return nchars;
+}
+
+
+// Format a string
+//
+// If the string is the NULL pointer then normally "(null)" is printed
+// unless the precision is < 6, in which case the empty string is printed.
+// The specification leaves it as undefined what happens if a string requests
+// 0 padding; Here we always pad with blanks (although GCC/PowerPC catches
+// this as an error).
+
+static ssize_t
+format_string(FILE* stream, const char* s, int options,
+ size_t width, size_t precision)
+{
+ size_t len;
+ ssize_t padchars, nchars;
+ int rc;
+
+ if (s == 0)
+ {
+ if ((options & OPTION_PRECISION) && (precision < 6))
+ {
+ s = "";
+ }
+ else
+ {
+ s = "(null)";
+ }
+ }
+
+ len = strlen(s);
+
+ if (options & OPTION_PRECISION)
+ {
+ len = MIN(len, precision);
+ }
+
+ options &= ~OPTION_PAD_ZERO;
+ padchars = pad(stream, len, options, width);
+
+ if (padchars < 0)
+ {
+ return padchars;
+ }
+
+ nchars = padchars + len;
+ rc = swrite(stream, (void*)s, len, 0);
+
+ if (rc < 0)
+ {
+ return rc;
+ }
+
+ return nchars;
+}
+
+
+// Format an integer - signed and unsigned. A 64-bit integer (assumed to be
+// the longest we'll see) has 20 decimal digits. An extra space is reserved
+// for the sign. If zero-padding is specified, the sign will be output
+// separately.
+
+static const char lower[16] =
+{
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+};
+
+static const char upper[16] =
+{
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+};
+
+static ssize_t
+format_int(FILE* stream, long long int lli, int options, size_t width)
+{
+ char digits[21];
+ int rc, k, ndigits, negative, positive, i;
+ ssize_t output;
+
+ negative = (lli < 0);
+ positive = (lli > 0);
+
+ // Unpack the integer to characters. The code is optimized for 32-bit
+ // machines where 64-bit division is not built in. The first part of the
+ // loop handles integers requiring a 64-bit divide, the second loop
+ // handles 32-bit integers.
+
+ if (lli == 0)
+ {
+ digits[20] = '0';
+ k = 20;
+ }
+ else if (negative)
+ {
+ for (k = 21;
+ lli != (int)lli;
+ digits[--k] = lower[-(lli % 10)], lli = lli / 10);
+
+ for (i = (int)lli;
+ i != 0;
+ digits[--k] = lower[-(i % 10)], i = i / 10);
+ }
+ else
+ {
+ for (k = 21;
+ lli != (int)lli;
+ digits[--k] = lower[lli % 10], lli = lli / 10);
+
+ for (i = (int)lli;
+ i != 0;
+ digits[--k] = lower[i % 10], i = i / 10);
+ }
+
+ ndigits = 21 - k;
+
+ // Handle other options and output
+
+ output = 0;
+
+ if (options & OPTION_PAD_ZERO)
+ {
+
+ if (negative)
+ {
+ rc = swrite(stream, "-", 1, 0);
+
+ if (rc < 0)
+ {
+ return rc;
+ }
+
+ output++;
+ }
+ else if (positive)
+ {
+ if (options & OPTION_PLUS_SIGN)
+ {
+ rc = swrite(stream, "+", 1, 0);
+
+ if (rc < 0)
+ {
+ return rc;
+ }
+
+ output++;
+ }
+ else if (options & OPTION_SPACE)
+ {
+ rc = swrite(stream, " ", 1, 0);
+
+ if (rc < 0)
+ {
+ return rc;
+ }
+
+ output++;
+ }
+ }
+
+ rc = pad(stream, ndigits + output, options, width);
+
+ if (rc < 0)
+ {
+ return rc;
+ }
+
+ output += rc;
+ rc = swrite(stream, &(digits[k]), ndigits, 0);
+
+ if (rc < 0)
+ {
+ return rc;
+ }
+
+ output += ndigits;
+
+ }
+ else
+ {
+
+ if (negative)
+ {
+ digits[--k] = '-';
+ ndigits++;
+ }
+ else if (positive)
+ {
+ if (options & OPTION_PLUS_SIGN)
+ {
+ digits[--k] = '+';
+ ndigits++;
+ }
+ else if (options & OPTION_SPACE)
+ {
+ digits[--k] = ' ';
+ ndigits++;
+ }
+ }
+
+ rc = pad(stream, ndigits, options, width);
+
+ if (rc < 0)
+ {
+ return rc;
+ }
+
+ output += rc;
+ rc = swrite(stream, &(digits[k]), ndigits, 0);
+
+ if (rc < 0)
+ {
+ return rc;
+ }
+
+ output += ndigits;
+ }
+
+ return output;
+}
+
+
+static ssize_t
+format_unsigned(FILE* stream, unsigned long long ull, int options, size_t width)
+{
+ char digits[21], *alternate;
+ const char* xchars;
+ int rc, k, ndigits, zero;
+ unsigned u;
+ ssize_t output;
+
+ zero = (ull == 0);
+
+ // Determine hex case and alternate string
+
+ alternate = 0;
+
+ if (options & OPTION_HEX)
+ {
+ if (options & OPTION_UPPERCASE)
+ {
+ xchars = upper;
+
+ if (options & OPTION_ALTERNATE)
+ {
+ alternate = "0X";
+ }
+ }
+ else
+ {
+ xchars = lower;
+
+ if (options & OPTION_ALTERNATE)
+ {
+ alternate = "0x";
+ }
+ }
+ }
+ else
+ {
+ xchars = lower;
+ }
+
+ // Unpack the unsigned integer to characters. The Hex conversions are
+ // easier since they can be done with shift and mask rather than
+ // divison. The code is optimized for a 32-bit machine where 64-bit
+ // division is not built-in.
+
+ if (zero)
+ {
+ digits[20] = '0';
+ k = 20;
+ }
+ else if (options & OPTION_HEX)
+ {
+ for (k = 21;
+ ull != (unsigned)ull;
+ digits[--k] = xchars[ull & 0xf], ull = ull >> 4);
+
+ for (u = (unsigned)ull;
+ u != 0;
+ digits[--k] = xchars[u & 0xf], u = u >> 4);
+ }
+ else
+ {
+ for (k = 21;
+ ull != (unsigned)ull;
+ digits[--k] = xchars[ull % 10], ull = ull / 10);
+
+ for (u = (unsigned)ull;
+ u != 0;
+ digits[--k] = xchars[u % 10], u = u / 10);
+ }
+
+ ndigits = 21 - k;
+
+ // Handle other options and output
+
+ output = 0;
+
+ if (options & OPTION_PAD_ZERO)
+ {
+
+ if (!zero && alternate)
+ {
+ rc = swrite(stream, (void*)alternate, 2, 0);
+
+ if (rc < 0)
+ {
+ return rc;
+ }
+
+ output += 2;
+ }
+
+ rc = pad(stream, ndigits + output, options, width);
+
+ if (rc < 0)
+ {
+ return rc;
+ }
+
+ output += rc;
+ rc = swrite(stream, &(digits[k]), ndigits, 0);
+
+ if (rc < 0)
+ {
+ return rc;
+ }
+
+ output += ndigits;
+
+ }
+ else
+ {
+
+ if (!zero && alternate)
+ {
+ output += 2;
+ }
+
+ rc = pad(stream, ndigits + output, options, width);
+
+ if (rc < 0)
+ {
+ return rc;
+ }
+
+ output += rc;
+
+ if (!zero && alternate)
+ {
+ rc = swrite(stream, alternate, 2, 0);
+
+ if (rc < 0)
+ {
+ return rc;
+ }
+
+ output += 2;
+ }
+
+ rc = swrite(stream, &(digits[k]), ndigits, 0);
+
+ if (rc < 0)
+ {
+ return rc;
+ }
+
+ output += ndigits;
+ }
+
+ return output;
+}
+
+
+int
+vfprintf(FILE* stream, const char* format, va_list argp)
+{
+ const char* fmt, *scan;
+ int rc, total_chars, options, done;
+ size_t width, precision;
+
+ int arg_i, *arg_pi;
+ long int arg_li;
+ long long int arg_lli;
+ ssize_t arg_zi;
+ unsigned arg_u;
+ unsigned long arg_lu;
+ unsigned long long arg_llu;
+ size_t arg_zu;
+ char* arg_s;
+
+ total_chars = 0;
+
+ fmt = format;
+
+ while (*fmt)
+ {
+
+ // Scan until '%' or the end of the format, then output the text.
+
+ scan = fmt;
+
+ while (*scan && (*scan != '%'))
+ {
+ scan++;
+ }
+
+ if (scan != fmt)
+ {
+ rc = swrite(stream, fmt, scan - fmt, 0);
+
+ if (rc < 0)
+ {
+ return rc;
+ }
+
+ total_chars += scan - fmt;
+ }
+
+ fmt = scan;
+
+ if (!*fmt)
+ {
+ return total_chars;
+ }
+
+ fmt++;
+
+ // We got a '%'. Check for %% and %n.
+
+ switch (*fmt)
+ {
+ case '\0':
+ SSX_IO_ERROR(stream, EINVAL);
+ break;
+
+ case '%':
+ rc = swrite(stream, "%", 1, 0);
+
+ if (rc < 0)
+ {
+ return rc;
+ }
+
+ total_chars++;
+ fmt++;
+ continue;
+
+ case 'n':
+ arg_pi = va_arg(argp, int*);
+ *arg_pi = total_chars;
+ fmt++;
+ continue;
+ }
+
+ // Collect padding options, if any. Left justification is not
+ // implemeted.
+
+ options = 0;
+ done = 0;
+
+ do
+ {
+ switch (*fmt)
+ {
+ case '\0':
+ SSX_IO_ERROR(stream, EINVAL);
+ break;
+
+ case '#':
+ options |= OPTION_ALTERNATE;
+ break;
+
+ case '0':
+ options |= OPTION_PAD_ZERO;
+ break;
+
+ case '+':
+ options |= OPTION_PLUS_SIGN;
+ break;
+
+ case ' ':
+ options |= OPTION_SPACE;
+ break;
+
+ case '-':
+ SSX_IO_ERROR(stream, EINVAL); // Left just. not impl.
+ break;
+
+ default:
+ done = 1;
+ break;
+ }
+
+ if (!done)
+ {
+ fmt++;
+ }
+ }
+ while (!done);
+
+ // Collect the field width, if specified. A negative precision
+ // specified as an argument indicates left justification (not
+ // implemented).
+
+ width = 0;
+
+ if (isdigit(*fmt))
+ {
+ options |= OPTION_FIELD_WIDTH;
+
+ for (; isdigit(*fmt); fmt++)
+ {
+ width = (width * 10) + (*fmt - '0');
+ }
+ }
+ else if (*fmt == '*')
+ {
+ fmt++;
+ options |= OPTION_FIELD_WIDTH;
+ arg_i = va_arg(argp, int);
+
+ if (arg_i < 0)
+ {
+ SSX_IO_ERROR(stream, EINVAL); // Left just. not impl.
+ }
+
+ width = arg_i;
+ }
+
+ // Collect the precision, if specified. By standard specification an
+ // empty or negative precision is interpreted as 0.
+
+ precision = 0;
+
+ if (*fmt == '.')
+ {
+ fmt++;
+ options |= OPTION_PRECISION;
+
+ if (isdigit(*fmt))
+ {
+ for(; isdigit(*fmt); fmt++)
+ {
+ precision = (precision * 10) + (*fmt - '0');
+ }
+ }
+ else if (*fmt == '*')
+ {
+ fmt++;
+ arg_i = va_arg(argp, int);
+
+ if (arg_i < 0)
+ {
+ arg_i = 0;
+ }
+
+ precision = arg_i;
+ }
+ }
+
+ // Collect length modifiers.
+
+ done = 0;
+
+ do
+ {
+ switch (*fmt)
+ {
+ case '\0':
+ SSX_IO_ERROR(stream, EINVAL);
+ break;
+
+ case 'l':
+ if (options & OPTION_LONG)
+ {
+ options &= ~OPTION_LONG;
+ options |= OPTION_LONG_LONG;
+ }
+ else if (options & OPTION_LONG_LONG)
+ {
+ SSX_IO_ERROR(stream, EINVAL);
+ }
+ else
+ {
+ options |= OPTION_LONG;
+ }
+
+ if (options & OPTION_SIZE_T)
+ {
+ SSX_IO_ERROR(stream, EINVAL);
+ }
+
+ break;
+
+ case 'z':
+ if ((options & OPTION_LONG) || (options & OPTION_LONG_LONG))
+ {
+ SSX_IO_ERROR(stream, EINVAL);
+ }
+
+ options |= OPTION_SIZE_T;
+ break;
+
+ default:
+ done = 1;
+ break;
+ }
+
+ if (!done)
+ {
+ fmt++;
+ }
+ }
+ while (!done);
+
+ // Use the conversion specifier to format the next argument
+
+ switch (*fmt)
+ {
+
+ case 'c':
+ arg_i = va_arg(argp, int);
+ rc = format_char(stream, (unsigned char)arg_i, options, width);
+
+ if (rc < 0)
+ {
+ return rc;
+ }
+
+ total_chars++;
+ break;
+
+ case 'd':
+ case 'i':
+ if (options & OPTION_LONG)
+ {
+ arg_li = va_arg(argp, long int);
+ rc = format_int(stream, (long long int)arg_li, options,
+ width);
+ }
+ else if (options & OPTION_LONG_LONG)
+ {
+ arg_lli = va_arg(argp, long long int);
+ rc = format_int(stream, (long long int)arg_lli, options,
+ width);
+ }
+ else if (options & OPTION_SIZE_T)
+ {
+ arg_zi = va_arg(argp, ssize_t);
+ rc = format_int(stream, (long long int)arg_zi, options,
+ width);
+ }
+ else
+ {
+ arg_i = va_arg(argp, int);
+ rc = format_int(stream, (long long int)arg_i, options,
+ width);
+ }
+
+ if (rc < 0)
+ {
+ return rc;
+ }
+
+ total_chars += rc;
+ break;
+
+ case 'p':
+ arg_lu = va_arg(argp, unsigned long);
+ options |= (OPTION_ALTERNATE | OPTION_HEX);
+
+ if (!(options & OPTION_PAD_ZERO) &&
+ !(options & OPTION_FIELD_WIDTH))
+ {
+ options |= (OPTION_PAD_ZERO | OPTION_FIELD_WIDTH);
+ width = (2 * sizeof(unsigned long)) + 2; /* 0x........ */
+ }
+
+ if (arg_lu == 0)
+ {
+ options &= ~OPTION_PRECISION;
+ rc = format_string(stream, "(nil)", options, width, precision);
+ }
+ else
+ {
+ rc = format_unsigned(stream, (unsigned long long)arg_lu,
+ options, width);
+ }
+
+ if (rc < 0)
+ {
+ return rc;
+ }
+
+ total_chars += rc;
+ break;
+
+ case 's':
+ arg_s = va_arg(argp, char*);
+ rc = format_string(stream, arg_s, options, width, precision);
+
+ if (rc < 0)
+ {
+ return rc;
+ }
+
+ total_chars += rc;
+ break;
+
+ case 'X':
+ options |= OPTION_UPPERCASE;
+
+ case 'x':
+ options |= OPTION_HEX;
+
+ case 'u':
+ if (options & OPTION_LONG)
+ {
+ arg_lu = va_arg(argp, unsigned long);
+ rc = format_unsigned(stream, (unsigned long long)arg_lu,
+ options, width);
+ }
+ else if (options & OPTION_LONG_LONG)
+ {
+ arg_llu = va_arg(argp, unsigned long long);
+ rc = format_unsigned(stream, (unsigned long long)arg_llu,
+ options, width);
+ }
+ else if (options & OPTION_SIZE_T)
+ {
+ arg_zu = va_arg(argp, size_t);
+ rc = format_unsigned(stream, (unsigned long long)arg_zu,
+ options, width);
+ }
+ else
+ {
+ arg_u = va_arg(argp, unsigned);
+ rc = format_unsigned(stream, (unsigned long long )arg_u,
+ options, width);
+ }
+
+ if (rc < 0)
+ {
+ return rc;
+ }
+
+ total_chars += rc;
+ break;
+
+ default:
+ SSX_IO_ERROR(stream, EINVAL);
+ break;
+ }
+
+ fmt++;
+ }
+
+ return total_chars;
+}
+
+
+int
+vprintf(const char* format, va_list argp)
+{
+ return vfprintf(stdout, format, argp);
+}
+
+
+int
+fprintf(FILE* stream, const char* format, ...)
+{
+ va_list argp;
+ int rc;
+
+ va_start(argp, format);
+ rc = vfprintf(stream, format, argp);
+ va_end(argp);
+ return rc;
+}
+
+
+int
+printf(const char* format, ...)
+{
+ va_list argp;
+ int rc;
+
+ va_start(argp, format);
+ rc = vfprintf(stdout, format, argp);
+ va_end(argp);
+ return rc;
+}
+
+
+int
+printk(const char* format, ...)
+{
+ va_list argp;
+ int rc;
+
+ va_start(argp, format);
+ rc = vfprintf(ssxout, format, argp);
+ va_end(argp);
+ return rc;
+}
diff --git a/import/chips/p9/common/pmlib/ppc405lib/puts.c b/import/chips/p9/common/pmlib/ppc405lib/puts.c
new file mode 100644
index 00000000..dc2214fa
--- /dev/null
+++ b/import/chips/p9/common/pmlib/ppc405lib/puts.c
@@ -0,0 +1,131 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/common/pmlib/ppc405lib/puts.c $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2015,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: puts.c,v 1.1.1.1 2013/12/11 20:49:20 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/puts.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file puts.c
+/// \brief Implementation of puts(), fputs(), putchar(), fputc()
+///
+/// The implementations of these APIs are split out to save code space for
+/// applications that do not require them.
+
+#include "ssx_io.h"
+
+
+/// Put a character to a stream
+///
+/// The fputc() function writes the byte specified by \a c (converted to an
+/// unsigned char) to the stream pointed to by \a stream. On success, fputc()
+/// returns the value written, i.e., the \c unsigned \c char form of \a c.
+///
+/// The POSIX standard fputc() returns EOF on error; this version returns the
+/// negative error code of the underlying I/O error, which will also be set in
+/// the \a error field of the \a stream. Note that SSX may also be configured
+/// to panic in the event of an I/O error.
+
+int
+fputc(int c, FILE* stream)
+{
+ unsigned char uc = (unsigned char)c;
+ int rc = swrite(stream, (void*)(&uc), 1, 0);
+
+ if (rc < 0)
+ {
+ return rc;
+ }
+ else
+ {
+ return uc;
+ }
+}
+
+
+/// Put a string to a stream
+///
+/// The fputs() function writes the null-terminated string \a s to the stream
+/// pointed to by \a stream. The terminating null byte is not written. On
+/// success, fputs() returns 0.
+///
+/// The POSIX standard fputc() returns EOF on error; this version returns the
+/// negative error code of the underlying I/O error, which will also be set in
+/// the \a error field of the \a stream. Note that SSX may also be configured
+/// to panic in the event of an I/O error.
+
+int
+fputs(const char* s, FILE* stream)
+{
+ return swrite(stream, s, strlen(s), 0);
+}
+
+/// Put a string to \c stdout
+///
+/// The puts() function writes the null-terminated string \a s followed by a
+/// newline to \a stdout. The terminating null byte is not written. On
+/// success, puts() returns 0.
+///
+/// The POSIX standard fputc() returns EOF on error; this version returns the
+/// negative error code of the underlying I/O error, which will also be set in
+/// the \a error field of the \a stream. Note that SSX may also be configured
+/// to panic in the event of an I/O error.
+
+int
+puts(const char* s)
+{
+ int rc = fputs(s, stdout);
+
+ if (rc < 0)
+ {
+ return rc;
+ }
+ else
+ {
+ rc = fputc('\n', stdout);
+
+ if (rc < 0)
+ {
+ return rc;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+}
+
+
+/// Put a character to \a stdout.
+///
+/// \c putchar(c) is equivalent to <c> fputc(c, stdout) </c>.
+
+int
+putchar(int c)
+{
+ return fputc(c, stdout);
+}
diff --git a/import/chips/p9/common/pmlib/ppc405lib/simics_stdio.c b/import/chips/p9/common/pmlib/ppc405lib/simics_stdio.c
new file mode 100644
index 00000000..33678474
--- /dev/null
+++ b/import/chips/p9/common/pmlib/ppc405lib/simics_stdio.c
@@ -0,0 +1,190 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/common/pmlib/ppc405lib/simics_stdio.c $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2015,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: simics_stdio.c,v 1.1.1.1 2013/12/11 20:49:20 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/simics_stdio.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file simics_stdio.c
+/// \brief SSX I/O drivers for Simics stdio streams
+///
+/// The Simics 'stdio' component is a pseudo serial port for I/O to stdio,
+/// stdout and stderr, as well as to other configurable streams. Each virtual
+/// file potentially has a read port, write port and flush port.
+///
+/// The write ports accept 1, 2 and 4-byte transactions on a 32-bit OCI
+/// address and write the data to the associated stream. Writing any value to
+/// the flush port flushes the output stream. The input ports are not yet
+/// implemented.
+
+#include "ssx.h"
+#include "simics_stdio.h"
+
+
+SimicsStdio simics_stdin;
+SimicsStdio simics_stdout;
+SimicsStdio simics_stderr;
+
+int
+simics_stdio_sread(FILE* stream, void* buf, size_t count, size_t* read)
+{
+ SSX_PANIC(ENXIO);
+ return -ENXIO;
+}
+
+
+int
+simics_stdio_swrite(FILE* stream, const void* buf,
+ size_t count, size_t* written)
+{
+ SimicsStdio* simics = (SimicsStdio*)stream;
+ size_t n;
+
+ n = count;
+
+ while (n)
+ {
+ if (n >= 4)
+ {
+ out32(simics->write_address, *((uint32_t*)buf));
+ buf += 4;
+ n -= 4;
+ }
+ else if (n >= 2)
+ {
+ out16(simics->write_address, *((uint16_t*)buf));
+ buf += 2;
+ n -= 2;
+ }
+ else
+ {
+ out8(simics->write_address, *((uint8_t*)buf));
+ buf++;
+ n--;
+ }
+ }
+
+ *written = count;
+
+ return 0;
+}
+
+
+ssize_t
+simics_stdio_fflush(FILE* stream)
+{
+ SimicsStdio* simics = (SimicsStdio*)stream;
+
+ out8(simics->flush_address, 0);
+ return 0;
+}
+
+
+/// Create a SimicsStdio stream
+///
+/// Any of the \a read_address, \a write_address or \a flush_address which are
+/// non-0 specify that the stream supports the associated method. The Simics
+/// I/O drivers do not require locking.
+
+int
+simics_stdio_create(SimicsStdio* stream,
+ SsxAddress read_address,
+ SsxAddress write_address,
+ SsxAddress flush_address)
+{
+ FILE* base = (FILE*)stream;
+ int rc;
+
+ if (SSX_ERROR_CHECK_API)
+ {
+ SSX_ERROR_IF(stream == 0, EBADF);
+ }
+
+ rc = FILE_create((FILE*)stream, 0);
+
+ if (!rc)
+ {
+
+ stream->read_address = read_address;
+
+ if (read_address != 0)
+ {
+ base->sread = simics_stdio_sread;
+ }
+
+ stream->write_address = write_address;
+
+ if (write_address != 0)
+ {
+ base->swrite = simics_stdio_swrite;
+ }
+
+ stream->flush_address = flush_address;
+
+ if (flush_address != 0)
+ {
+ base->fflush = simics_stdio_fflush;
+ }
+ }
+
+ return rc;
+}
+
+
+int
+simics_stdin_create(SimicsStdio* stream)
+{
+ return simics_stdio_create(stream, SIMICS_STDIN, 0, 0);
+}
+
+
+int
+simics_stdout_create(SimicsStdio* stream)
+{
+ return simics_stdio_create(stream, 0, SIMICS_STDOUT, SIMICS_STDOUT_FLUSH);
+}
+
+int
+simics_stderr_create(SimicsStdio* stream)
+{
+ return simics_stdio_create(stream, 0, SIMICS_STDERR, SIMICS_STDERR_FLUSH);
+}
+
+int
+simics_stdfile_create(SimicsStdio* stream, int fn)
+{
+ if (SSX_ERROR_CHECK_API)
+ {
+ SSX_ERROR_IF((fn < 0) > (fn >= SIMICS_STDFILE_STREAMS), EBADF);
+ }
+
+ return simics_stdio_create(stream,
+ SIMICS_STDFILE_READ(fn),
+ SIMICS_STDFILE_WRITE(fn),
+ SIMICS_STDFILE_FLUSH(fn));
+}
diff --git a/import/chips/p9/common/pmlib/ppc405lib/simics_stdio.h b/import/chips/p9/common/pmlib/ppc405lib/simics_stdio.h
new file mode 100644
index 00000000..9ab2b4bb
--- /dev/null
+++ b/import/chips/p9/common/pmlib/ppc405lib/simics_stdio.h
@@ -0,0 +1,94 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/common/pmlib/ppc405lib/simics_stdio.h $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2015,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __SIMICS_STDIO_H__
+#define __SIMICS_STDIO_H__
+
+// $Id: simics_stdio.h,v 1.1.1.1 2013/12/11 20:49:20 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/simics_stdio.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file simics_stdio.h
+/// \brief SSX I/O implementations for Simics stdio streams
+
+#include "ssx_io.h"
+#include "simics_stdio_addresses.h"
+#include "string.h"
+
+/// A FILE structure for a Simics fake stdio stream
+
+typedef struct
+{
+
+ /// The base class
+ FILE stream;
+
+ /// The MMIO address of the Simics read port for the stream
+ SsxAddress read_address;
+
+ /// The MMIO address of the Simics write port for the stream
+ SsxAddress write_address;
+
+ /// The MMIO address of the Simics device for flushing the stream;
+ SsxAddress flush_address;
+
+} SimicsStdio;
+
+extern SimicsStdio simics_stdin;
+extern SimicsStdio simics_stdout;
+extern SimicsStdio simics_stderr;
+
+int
+simics_stdio_create(SimicsStdio* stream,
+ SsxAddress read_address,
+ SsxAddress write_address,
+ SsxAddress flush_address);
+
+int
+simics_stdin_create(SimicsStdio* stream);
+
+int
+simics_stdout_create(SimicsStdio* stream);
+
+int
+simics_stderr_create(SimicsStdio* stream);
+
+int
+simics_stdfile_create(SimicsStdio* stream, int fn);
+
+int
+simics_stdio_sread(FILE* stream, void* buf, size_t count, size_t* read);
+
+int
+simics_stdio_swrite(FILE* stream, const void* buf,
+ size_t count, size_t* written);
+
+int
+simics_stdio_sflush(FILE* stream);
+
+#endif /* __SIMICS_STDIO_H__ */
diff --git a/import/chips/p9/common/pmlib/ppc405lib/simics_stdio_addresses.h b/import/chips/p9/common/pmlib/ppc405lib/simics_stdio_addresses.h
new file mode 100644
index 00000000..fe5daad3
--- /dev/null
+++ b/import/chips/p9/common/pmlib/ppc405lib/simics_stdio_addresses.h
@@ -0,0 +1,91 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/common/pmlib/ppc405lib/simics_stdio_addresses.h $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2015,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __SIMICS_STDIO_ADDRESSES_H__
+#define __SIMICS_STDIO_ADDRESSES_H__
+
+// $Id: simics_stdio_addresses.h,v 1.1.1.1 2013/12/11 20:49:20 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/simics_stdio_addresses.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file simics_stdio_adresses.h
+/// \brief MMIO addresses and offsets of the Simics fake stdio model
+///
+/// The Simics 'stdio' component is a pseudo serial port for I/O to stdio,
+/// stdout and stderr, as well as to other configurable streams. Each virtual
+/// file potentially has a read port, write port and flush port.
+///
+/// The write ports accept 1, 2 and 4-byte transactions on a 32-bit OCI
+/// address and write the data to the associated stream. Writing any value to
+/// the flush port flushes the output stream. The input ports are not yet
+/// implemented.
+
+// -*- This header is maintained as part of the PMX Simics model. -*-
+// -*- Do not edit in the SSX library as your edits will be lost. -*-
+
+#define SIMICS_STDIO_BASE 0x40060000
+
+#define SIMICS_STDIN_OFFSET 0x00
+#define SIMICS_STDOUT_OFFSET 0x04
+#define SIMICS_STDOUT_FLUSH_OFFSET 0x08
+#define SIMICS_STDERR_OFFSET 0x0c
+#define SIMICS_STDERR_FLUSH_OFFSET 0x10
+
+#define SIMICS_STDFILE_0_OFFSET 0x14
+#define SIMICS_STDFILE_1_OFFSET 0x20
+#define SIMICS_STDFILE_2_OFFSET 0x2c
+#define SIMICS_STDFILE_3_OFFSET 0x38
+
+#define SIMICS_STDFILE_STREAMS 4
+
+#define SIMICS_STDIN (SIMICS_STDIO_BASE + SIMICS_STDIN_OFFSET)
+#define SIMICS_STDOUT (SIMICS_STDIO_BASE + SIMICS_STDOUT_OFFSET)
+#define SIMICS_STDOUT_FLUSH (SIMICS_STDIO_BASE + SIMICS_STDOUT_FLUSH_OFFSET)
+#define SIMICS_STDERR (SIMICS_STDIO_BASE + SIMICS_STDERR_OFFSET)
+#define SIMICS_STDERR_FLUSH (SIMICS_STDIO_BASE + SIMICS_STDERR_FLUSH_OFFSET)
+
+#define SIMICS_STDFILE_READ_OFFSET(fn) \
+ (SIMICS_STDFILE_0_OFFSET + (12 * fn) + 0x00)
+
+#define SIMICS_STDFILE_WRITE_OFFSET(fn) \
+ (SIMICS_STDFILE_0_OFFSET + (12 * fn) + 0x04)
+
+#define SIMICS_STDFILE_FLUSH_OFFSET(fn) \
+ (SIMICS_STDFILE_0_OFFSET + (12 * fn) + 0x08)
+
+#define SIMICS_STDFILE_READ(fn) \
+ (SIMICS_STDIO_BASE + SIMICS_STDFILE_READ_OFFSET(fn))
+
+#define SIMICS_STDFILE_WRITE(fn) \
+ (SIMICS_STDIO_BASE + SIMICS_STDFILE_WRITE_OFFSET(fn))
+
+#define SIMICS_STDFILE_FLUSH(fn) \
+ (SIMICS_STDIO_BASE + SIMICS_STDFILE_FLUSH_OFFSET(fn))
+
+
+#endif /* __SIMICS_STDIO_ADDRESSES_H__ */
diff --git a/import/chips/p9/common/pmlib/ppc405lib/sprintf.c b/import/chips/p9/common/pmlib/ppc405lib/sprintf.c
new file mode 100644
index 00000000..6011ad9c
--- /dev/null
+++ b/import/chips/p9/common/pmlib/ppc405lib/sprintf.c
@@ -0,0 +1,138 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/common/pmlib/ppc405lib/sprintf.c $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2015,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: sprintf.c,v 1.1.1.1 2013/12/11 20:49:20 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/sprintf.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file sprintf.c \brief Implementations of sprintf() and snprintf() using
+/// StringStream.
+
+#include "ssx.h"
+#include "ssx_io.h"
+#include "string_stream.h"
+
+
+// sprintf() is easy - just blindly copy in the data.
+
+static int
+sprintf_swrite(FILE* stream, const void* buf, size_t size, size_t* written)
+{
+ StringStream* string = (StringStream*)stream;
+
+ memcpy((void*)(&(string->data[string->next_write])), buf, size);
+ string->next_write += size;
+ *written = size;
+ return 0;
+}
+
+
+// snprintf() requires that bytes that won't fit in the array are simply
+// discarded, but still accounted for. Note that vfprintf() is doing the
+// high-level accounting.
+
+static int
+snprintf_swrite(FILE* stream, const void* buf, size_t size, size_t* written)
+{
+ StringStream* string = (StringStream*)stream;
+
+ size_t to_write = MIN(size, string->size - string->next_write - 1);
+
+ memcpy((void*)(&(string->data[string->next_write])), buf, to_write);
+ string->next_write += to_write;
+ *written = size;
+ return 0;
+}
+
+
+// We use a StringStream to implement [v]sprintf() and [v]snprintf(). Once
+// the formatting is finished the NULL terminator is added.
+
+int
+vsprintf(char* str, const char* format, va_list argp)
+{
+ ssize_t rc;
+ StringStream stream;
+
+ _string_stream_create(&stream, str, 1, 0, sprintf_swrite);
+ rc = vfprintf((FILE*)(&stream), format, argp);
+ stream.data[stream.next_write] = 0;
+ return rc;
+}
+
+
+
+int
+sprintf(char* str, const char* format, ...)
+{
+ va_list argp;
+ ssize_t rc;
+
+ va_start(argp, format);
+ rc = vsprintf(str, format, argp);
+ va_end(argp);
+
+ return rc;
+}
+
+
+int
+vsnprintf(char* str, size_t size, const char* format, va_list argp)
+{
+ ssize_t rc;
+ StringStream stream;
+
+ if (size == 0)
+ {
+ return 0;
+ }
+
+ _string_stream_create(&stream, str, size, 0, snprintf_swrite);
+ rc = vfprintf((FILE*)(&stream), format, argp);
+ stream.data[stream.next_write] = 0;
+ return rc;
+}
+
+
+int
+snprintf(char* str, size_t size, const char* format, ...)
+{
+ va_list argp;
+ ssize_t rc;
+
+ if (size == 0)
+ {
+ return 0;
+ }
+
+ va_start(argp, format);
+ rc = vsnprintf(str, size, format, argp);
+ va_end(argp);
+
+ return rc;
+}
diff --git a/import/chips/p9/common/pmlib/ppc405lib/ssx_dump.c b/import/chips/p9/common/pmlib/ppc405lib/ssx_dump.c
new file mode 100644
index 00000000..bbd82e71
--- /dev/null
+++ b/import/chips/p9/common/pmlib/ppc405lib/ssx_dump.c
@@ -0,0 +1,245 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/common/pmlib/ppc405lib/ssx_dump.c $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2015,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: ssx_dump.c,v 1.1.1.1 2013/12/11 20:49:20 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/ssx_dump.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ssx_dump.c
+/// \brief Routines for dumping SSX kernel data structures
+///
+/// \note This is a quick hack to help solve a P8 bringup issue. This code is
+/// PPC405 (OCC) specific, i.e., not "portable" SSX. Ideally this type of dump
+/// would be implemented in an external debugging tool as well, however it's
+/// simplest to implement here in the execution context.
+
+#include "ssx_dump.h"
+
+#define SSX_DUMP_UNIMPLEMENTED 0x00d86701
+
+static const char* _threadState[] =
+{
+ 0,
+ "Suspended Runnable",
+ "Mapped",
+ "Suspended Blocked",
+ "Completed",
+ "Deleted",
+};
+
+static const char* _threadFlags[] =
+{
+ 0,
+ "Semaphore Pend",
+ "Timer Pend",
+ "Timer Pend | Semaphore Pend",
+ "Timed Out",
+ "Timed Out | Semaphore Pend",
+ "Timed Out | Timer Pend",
+ "Timed Out | Timer Pend | Semaphore Pend",
+};
+
+
+static void
+_dumpTimer(FILE* stream, SsxTimer* timer)
+{
+ fprintf(stream,
+ "-- Timer @ %p\n"
+ "-- Deque.previous = %p\n"
+ "-- Deque.next = %p\n"
+ "-- Timeout = 0x%016llx\n"
+ "-- Period = 0x%016llx\n"
+ "-- Callback = %p\n"
+ "-- Arg = %p\n"
+ "-- Options = 0x%02x\n",
+ timer,
+ timer->deque.previous,
+ timer->deque.next,
+ timer->timeout,
+ (unsigned long long)(timer->period),
+ timer->callback,
+ timer->arg,
+ timer->options);
+}
+
+
+static void
+_dumpThread(FILE* stream, SsxThread* thread)
+{
+ SsxThreadContext* threadCtx;
+ SsxThreadContextFullIrq* threadCtxIrq;
+ uint32_t srr[4], lr, sp;
+
+ fprintf(stream,
+ "-- Thread mapped at priority %d (%p)\n"
+ "-- Thread state = %s (%d)\n"
+ "-- Thread flags = %s (0x%02x)\n"
+ "-- Saved Stack Pointer = %p\n",
+ thread->priority, thread,
+ _threadState[thread->state], thread->state,
+ _threadFlags[thread->flags], thread->flags,
+ (void*)thread->saved_stack_pointer);
+
+ if (thread->flags & SSX_THREAD_FLAG_SEMAPHORE_PEND)
+ {
+
+ fprintf(stream,
+ "-- Semaphore = %p\n",
+ (void*)thread->semaphore);
+ }
+
+ fprintf(stream,
+ "---------------------------------------------\n");
+
+ if (thread->flags & SSX_THREAD_FLAG_TIMER_PEND)
+ {
+
+ _dumpTimer(stream, &(thread->timer));
+ fprintf(stream,
+ "---------------------------------------------\n");
+ }
+
+ if ((thread == ssx_current()) && !__ssx_kernel_context_any_interrupt())
+ {
+
+ fprintf(stream,
+ "-- This thread is executing ssx_dump()\n");
+
+ }
+ else
+ {
+
+ if (thread == ssx_current())
+ {
+
+ // This is the interrupted thread, and only has its volatile
+ // context saved. The thread stack pointer is stored in a global
+ // kernel variable.
+
+ if (__ssx_kernel_context_critical_interrupt())
+ {
+
+ SSX_PANIC(SSX_DUMP_UNIMPLEMENTED);
+ srr[0] = srr[1] = srr[2] = srr[3] = lr = sp = 0; /* For GCC */
+
+ }
+ else
+ {
+
+ threadCtxIrq =
+ (SsxThreadContextFullIrq*)__ssx_saved_sp_noncritical;
+ srr[0] = threadCtxIrq->srr0;
+ srr[1] = threadCtxIrq->srr1;
+ srr[2] = threadCtxIrq->srr2;
+ srr[3] = threadCtxIrq->srr3;
+ lr = threadCtxIrq->lr;
+ sp = threadCtxIrq->r1;
+ }
+ }
+ else
+ {
+
+ // This is a fully swapped-out thread. The context is saved in
+ // at the stored stack pointer.
+
+ threadCtx = (SsxThreadContext*)(thread->saved_stack_pointer);
+ srr[0] = threadCtx->srr0;
+ srr[1] = threadCtx->srr1;
+ srr[2] = threadCtx->srr2;
+ srr[3] = threadCtx->srr3;
+ lr = threadCtx->lr;
+ sp = ((uint32_t*)threadCtx->r1)[0];
+ }
+
+ fprintf(stream,
+ "-- SRR0: 0x%08x SRR1: 0x%08x "
+ "SRR2: 0x%08x SRR3: 0x%08x\n"
+ "-- LR: 0x%08x\n",
+ srr[0], srr[1], srr[2], srr[3],
+ lr);
+
+ fprintf(stream,
+ "---------------------------------------------\n");
+
+ // Unwind the stack
+
+ while (sp != 0)
+ {
+
+ fprintf(stream,
+ "-- SP: 0x%08x *LR*:0x%08x\n",
+ sp, ((uint32_t*)sp)[1]);
+ sp = ((uint32_t*)sp)[0];
+ }
+ }
+}
+
+
+
+
+void
+ssx_dump(FILE* stream, int options)
+{
+ int i, sep;
+ SsxThread* thread;
+
+ fprintf(stream,
+ "------------------------------------------------------------\n");
+ fprintf(stream,
+ "-- SSX Kernel Dump @ 0x%016llx\n"
+ "-- USPRG0 = 0x%08x\n"
+ "-- __ssx_run_queue = 0x%08x\n",
+ ssx_timebase_get(),
+ mfspr(SPRN_USPRG0),
+ __ssx_run_queue);
+ fprintf(stream,
+ "------------------------------------------------------------\n");
+
+ sep = 0;
+
+ for (i = 0; i < SSX_THREADS; i++)
+ {
+
+ ssx_thread_at_priority(i, &thread);
+
+ if (thread)
+ {
+ if (sep)
+ {
+ fprintf(stream,
+ "*********************************************\n");
+ }
+
+ _dumpThread(stream, thread);
+ sep = 1;
+ }
+ }
+
+ fprintf(stream,
+ "------------------------------------------------------------\n");
+}
diff --git a/import/chips/p9/common/pmlib/ppc405lib/ssx_dump.h b/import/chips/p9/common/pmlib/ppc405lib/ssx_dump.h
new file mode 100644
index 00000000..2be84bae
--- /dev/null
+++ b/import/chips/p9/common/pmlib/ppc405lib/ssx_dump.h
@@ -0,0 +1,82 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/common/pmlib/ppc405lib/ssx_dump.h $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2015,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __SSX_DUMP_H__
+#define __SSX_DUMP_H__
+
+// $Id: ssx_dump.h,v 1.1.1.1 2013/12/11 20:49:20 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/ssx_dump.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ssx_dump.h
+/// \brief Routines for dumping SSX kernel data structures
+
+#include "ssx.h"
+
+/// \defgroup ssx_dump_options Options for ssx_dump()
+///
+/// No options are currently specified.
+///
+/// @{
+
+/// @}
+
+#ifndef __ASSEMBLER__
+
+ /// Dump the kernel state
+ ///
+ /// \param i_stream The stream to receive the dump. If the dump is being
+ /// generated prior to a kernel panic then this would typically be \a ssxout,
+ /// the stream used by printk.
+ ///
+ /// \param i_options AN OR-mask of option flags; See \ref ssx_dump_options
+ ///
+ /// The SSX kernel dump produces a formatted snapshot of the state of the
+ /// kernel and the mapped threads. This API does not manipulate the machine
+ /// context; If it is required to produce a precise snapshot then the caller
+ /// will need to make the call from a critical section.
+ ///
+ /// The following information is standard in the dump
+ ///
+ /// - The interrupt and thread state of the kernel
+ /// - The state of each thread
+ /// - A stack trace for each thread
+ ///
+ /// Options : TBD
+ ///
+ /// \bug There are likely several bugs in the current implementation due to
+ /// the assumption that the code is being called from a state in which the
+ /// kernel context is not changing. We don't have time to code and test the
+ /// most general implementation now. To guarantee correct operation the API
+ /// must currently be called from an SSX_CRITICAL critical section.
+ void
+ ssx_dump(FILE* stream, int options);
+
+#endif // __ASSEMBLER__
+
+#endif // __SSX_DUMP_H__
diff --git a/import/chips/p9/common/pmlib/ppc405lib/ssx_io.c b/import/chips/p9/common/pmlib/ppc405lib/ssx_io.c
new file mode 100644
index 00000000..adf67770
--- /dev/null
+++ b/import/chips/p9/common/pmlib/ppc405lib/ssx_io.c
@@ -0,0 +1,363 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/common/pmlib/ppc405lib/ssx_io.c $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2015,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: ssx_io.c,v 1.2 2014/02/03 01:30:25 daviddu Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/ssx_io.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ssx_io.c
+/// \brief SSX analog-replacement for C \<stdio.h\> and \<unistd.h\> functions
+///
+/// The SSX library provides simple analogs for I/O functions found in the
+/// typical C libraries and Posix standards. I/O is not considered part of the
+/// SSX kernel per-se - I/O is implemented by the application creating I/O
+/// abstractions and drivers using the simple SSX kernel services. [However,
+/// the ssx_io library does provide a printk() function for use by kernel
+/// drivers, so the lines are not completely clear.]
+///
+/// This library provides a FILE structure or 'base class' to represent a
+/// character stream. Abstractions for different devices will 'derive' a
+/// subclass from this base class by including the FILE as the first member of
+/// the subclass, and then likely adding more data members. The FILE
+/// structure contains pointers to the routines that implement I/O operations
+/// for derived classes. There is no requiremengt that a stream type implement
+/// every possible stream operation. If an unsupported operation is invoked
+/// on a stream then the call will simply return -ENXIO, unless otherwise
+/// specified.
+///
+/// The generic I/O calls use the same error-handling protocol as used by the
+/// SSX kernel services. A configuration setting (\c SSX_ERROR_CHECK_API)
+/// determines if error checks are made at all, and another setting (\c
+/// SSX_ERROR_PANIC) determines whether the presence of a fatal error causes a
+/// bad return code or an immediate panic.
+///
+/// The following errors are never considered fatal errors:
+///
+/// \b EOF Used to signal end-of-file
+///
+/// \b EAGAIN Used to signal that an operation was made to a non-blocking
+/// stream and the call would block.
+///
+/// Following are the specifications and requirements for the stream methods
+/// that implement a stream type.
+///
+/// <b> int sread(FILE *stream, void *buf, size_t count, size_t *read) </b>
+///
+/// The low-level read() function is named sread() here due to differences in
+/// the prototype and semantics from the Unix counterpart. The sread()
+/// functions attempts to read \a count bytes from the \a stream into \a buf,
+/// sets the number of bytes read, and returns either 0 for success or a
+/// negative error code. The only reason that sread() may terminate without
+/// reading \a count bytes is if sread() also returns a negative return
+/// code.
+///
+/// The device-specific sread() function may assume that the \a stream, \a buf
+/// and \a read parameters are non-NULL at entry, and the \a count is greater
+/// than 0. These conditions are checked/guaranteed by the generic interface.
+///
+/// <b> int swrite(FILE *stream, void *buf, size_t count, size_t *written) </b>
+///
+/// The low-level write() function is named swrite() here due to differences
+/// in the prototype and semantics from the Unix counterpart. The swrite()
+/// function attempts to writes \a count bytes from buf to the \a stream, sets
+/// the number of bytes written, and returns either 0 for success or a
+/// negative error code. The only reason that swrite() may terminate without
+/// writing \a count bytes is if write() also returns a negative return
+/// code.
+///
+/// The device-specific swrite() function may assume that the \a stream, \a
+/// buf and \a written parameters are non-NULL at entry, and the \a count is
+/// greater than 0. These conditions are checked/guaranteed by the generic
+/// interface.
+///
+/// <b> int fflush(FILE *stream) </b>
+///
+/// SSX implements the fflush() call, even though the semantics are slightly
+/// different from the Posix standard. The Posix fflush() returns either 0
+/// for success, or EOF to indicate an error. Here, fflush() returns negative
+/// 'errno' codes directly in the event of errors. The Posix standard
+/// specifies that calling fflush() with a NULL \a stream causes all open
+/// files to be flushed - here it returns the -EBADF error.
+///
+/// The stream-specific fflush() implementation should return one of the
+/// 'errno' codes specified by the Posix standard in the event of
+/// problems.
+
+#include "ssx.h"
+#include "ssx_io.h"
+
+/// Initialize an SSX I/O FILE structure
+///
+/// \param file A pointer to an uninitialized FILE
+///
+/// \param flags Flags for the generic FILE
+///
+/// This API is designed to be called from "constructors of classes derived
+/// from FILE", e.g., the StringStream. The generic FILE structure is
+/// cleared, and the flags are installed and other initialization based on the
+/// flags is performed. The subclass constructors then install function
+/// pointers for any of the FILE functions that they implement.
+///
+/// \retval 0 Success
+///
+/// \retval -FILE_INVALID_OBJECT The \a file pointer is null (0).
+///
+/// \retval -FILE_INVALID_ARGUMENT The \a flags are not valid.
+
+int
+FILE_create(FILE* file, int flags)
+{
+ if (SSX_ERROR_CHECK_API)
+ {
+ SSX_ERROR_IF(file == 0, FILE_INVALID_OBJECT);
+ SSX_ERROR_IF(flags & ~SSX_FILE_VALID_FLAGS, FILE_INVALID_ARGUMENT);
+ SSX_ERROR_IF(__builtin_popcount(flags & SSX_FILE_OP_LOCK_OPTIONS) > 1,
+ FILE_INVALID_ARGUMENT);
+ }
+
+ memset((void*)file, 0, sizeof(FILE));
+ file->flags = flags;
+ ssx_semaphore_create(&(file->fop_sem), 1, 1);
+ return 0;
+}
+
+
+/// Assign an error code to a stream, returning a non-zero value for errors
+/// considered fatal.
+
+int
+ssx_io_error_set(FILE* stream, int code)
+{
+ if (SSX_ERROR_CHECK_API)
+ {
+ SSX_ERROR_IF(stream == 0, EBADF);
+ }
+
+ stream->error = code;
+
+ if ((code == EOF) ||
+ (code == EAGAIN))
+ {
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+}
+
+
+static int
+null_stream_sread(FILE* stream, void* buf, size_t count, size_t* read)
+{
+ *read = 0;
+ ssx_io_error_set(stream, EOF);
+ return EOF;
+}
+
+
+static int
+null_stream_swrite(FILE* stream, const void* buf, size_t count, size_t* written)
+{
+ *written = count;
+ return 0;
+}
+
+
+static int
+null_stream_fflush(FILE* stream)
+{
+ return 0;
+}
+
+
+/// A null stream; equivalent to Unix /dev/null
+///
+/// This stream is statically initialized as it is required to be assigned to
+/// \a ssxout at load time. The NULL stream does not require any locking.
+
+FILE _null_stream =
+{
+ .sread = null_stream_sread,
+ .swrite = null_stream_swrite,
+ .fflush = null_stream_fflush,
+ .error = 0,
+ .flags = 0
+};
+
+
+// It's up to the application to initialize the standard streams if it wishes
+// to use them. Reading or writing a NULL stream will signal an error.
+
+FILE* stdin = 0;
+FILE* stdout = 0;
+FILE* stderr = 0;
+
+/// Stream used by printk()
+///
+/// \a ssxout is the stream used by printk(). \a ssxout \e must be assigned
+/// to a non-blocking stream as it may be called from interrupt handlers. \a
+/// ssxout defaults to _null_stream, the equivalent of Unix' /dev/null.
+
+FILE* ssxout = &_null_stream;
+
+
+/// /dev/null for SSX
+FILE* ssxnull = &_null_stream;
+
+
+/// Lock low-level file operations
+///
+/// The decision on if and how low-level FILE operations needs to be locked is
+/// made by the class derived from FILE, and may also require an argument
+/// about its intended use. The minimum bar is always correctness. The next
+/// bar is whether the application allows data from multiple writers to be
+/// intermixed, or allows multiple readers to access the same input stream.
+///
+/// A device like the StringStream used to implement sprintf() and snprintf()
+/// does not require locking at all because it is only called from a single
+/// context. String streams that implement circular buffers must be locked if
+/// there is the possibility of multiple readers or writers, and the wrapping
+/// buffer always needs to be locked.
+///
+/// The lock implemented here is a lock on the low-level stream operations
+/// sread(), swrite() and fflush().
+
+#define LOCK_FILE_OPERATION(stream, operation) \
+ ({ \
+ int __rc; \
+ SsxMachineContext __ctx = SSX_THREAD_MACHINE_CONTEXT_DEFAULT; /* GCC */ \
+ if ((stream)->flags & SSX_FILE_OP_LOCK_OPTIONS) { \
+ if ((stream)->flags & SSX_FILE_OP_LOCK_CRITICAL) { \
+ ssx_critical_section_enter(SSX_CRITICAL, &__ctx); \
+ } else if ((stream)->flags & SSX_FILE_OP_LOCK_NONCRITICAL) { \
+ ssx_critical_section_enter(SSX_NONCRITICAL, &__ctx); \
+ } else { \
+ ssx_semaphore_pend(&((stream)->fop_sem), SSX_WAIT_FOREVER); \
+ } \
+ } \
+ __rc = (operation); \
+ if ((stream)->flags & SSX_FILE_OP_LOCK_OPTIONS) { \
+ if ((stream)->flags & (SSX_FILE_OP_LOCK_CRITICAL | \
+ SSX_FILE_OP_LOCK_NONCRITICAL)) { \
+ ssx_critical_section_exit(&__ctx); \
+ } else { \
+ ssx_semaphore_post(&((stream)->fop_sem)); \
+ } \
+ } \
+ __rc; \
+ })
+
+
+/// Call the sread() operation of a stream
+
+int
+sread(FILE* stream, void* buf, size_t count, size_t* read)
+{
+ ssize_t rc;
+ size_t _read;
+
+ if (SSX_ERROR_CHECK_API)
+ {
+ SSX_ERROR_IF((stream == 0), EBADF);
+ SSX_IO_ERROR_IF(stream, (stream->sread == 0), ENXIO);
+ SSX_IO_ERROR_IF(stream, (buf == 0), EINVAL);
+ }
+
+ if (count == 0)
+ {
+ if (read != 0)
+ {
+ *read = 0;
+ }
+
+ return 0;
+ }
+
+ rc = LOCK_FILE_OPERATION(stream, stream->sread(stream, buf, count, &_read));
+
+ if (read != 0)
+ {
+ *read = _read;
+ }
+
+ return rc;
+}
+
+
+/// Call the swrite() operation of a stream
+
+ssize_t
+swrite(FILE* stream, const void* buf, size_t count, size_t* written)
+{
+ ssize_t rc;
+ size_t _written;
+
+ if (SSX_ERROR_CHECK_API)
+ {
+ SSX_ERROR_IF((stream == 0), EBADF);
+ SSX_IO_ERROR_IF(stream, (stream->swrite == 0), ENXIO);
+ SSX_IO_ERROR_IF(stream, (buf == 0), EINVAL);
+ }
+
+ if (count == 0)
+ {
+ rc = 0;
+ _written = 0;
+ }
+ else
+ {
+ rc = LOCK_FILE_OPERATION(stream,
+ stream->swrite(stream, buf, count, &_written));
+ }
+
+ if (written != 0)
+ {
+ *written = _written;
+ }
+
+ return rc;
+}
+
+
+/// Call the fflush() operation of the stream
+
+int
+fflush(FILE* stream)
+{
+ int rc;
+
+ if (SSX_ERROR_CHECK_API)
+ {
+ SSX_IO_ERROR_IF(stream, (stream == 0), EBADF);
+ SSX_IO_ERROR_IF(stream, (stream->fflush == 0), ENXIO);
+ }
+
+ rc = LOCK_FILE_OPERATION(stream, stream->fflush(stream));
+ return rc;
+}
diff --git a/import/chips/p9/common/pmlib/ppc405lib/ssx_io.h b/import/chips/p9/common/pmlib/ppc405lib/ssx_io.h
new file mode 100644
index 00000000..c6ef55d8
--- /dev/null
+++ b/import/chips/p9/common/pmlib/ppc405lib/ssx_io.h
@@ -0,0 +1,229 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/common/pmlib/ppc405lib/ssx_io.h $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2015,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __SSX_IO_H__
+#define __SSX_IO_H__
+
+// $Id: ssx_io.h,v 1.2 2014/02/03 01:30:25 daviddu Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/ssx_io.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ssx_io.h
+/// \brief SSX analog-replacement for C <stdio.h> and <unistd.h> functions
+
+#if !defined(_STDIO_H) && !defined(_UNISTD_H)
+
+#include "ssx_macros.h"
+#include "ssx_api.h"
+
+#include "ctype.h"
+#include "errno.h"
+#include "string.h"
+
+#define EOF -1
+
+#define FILE_INVALID_OBJECT 0x00345301
+#define FILE_INVALID_ARGUMENT 0x00345302
+
+#ifndef __ASSEMBLER__
+
+#include <stdarg.h>
+
+/// The SSX implementation of the FILE structure
+
+typedef struct FILE
+{
+
+ /// The sread() method
+ int (*sread)(struct FILE* stream, void* buf,
+ size_t count, size_t* read);
+
+ /// The swrite() method
+ int (*swrite)(struct FILE* stream, const void* buf,
+ size_t count, size_t* written);
+
+ /// The fflush() method
+ int (*fflush)(struct FILE* stream);
+
+ /// The last error code encountered
+ ///
+ /// This field is not set in the event of an error panic.
+ int error;
+
+ /// SSX file/stream flags; See \ref ssx_file_flags
+ int flags;
+
+ /// The semaphore used to lock low-level file operations if required.
+ SsxSemaphore fop_sem;
+
+ /// The number of newline characters read by fgetc.
+ ///
+ /// This variable supports an SSX extension to <stdio.h>, the flines()
+ /// API. flines() returns the number of newline characters read by
+ /// fgetc(). This counter does not count newline characters read using
+ /// sread() on the stream directly.
+ size_t lines;
+
+ /// The character pushed back by ungetc()
+ ///
+ /// If a character is back the flag SSX_FILE_HAS_CHARACTER will be
+ /// set. Note that characters pushed back with ungetc() are not returned
+ /// by any subsequent sread() call on the stream, so it is best not to mix
+ /// sread() and fgetc().
+ unsigned char character;
+
+} FILE;
+
+
+/// \defgroup ssx_file_flags SSX File/Stream Flags
+/// @{
+
+/// Low-level access is locked by an SSX_CRITICAL critical section
+#define SSX_FILE_OP_LOCK_CRITICAL 0x1
+
+/// Low-level access is locked by an SSX_NONCRITICAL critical section
+#define SSX_FILE_OP_LOCK_NONCRITICAL 0x2
+
+/// Low-level access is locked by a semaphore
+#define SSX_FILE_OP_LOCK_SEMAPHORE 0x4
+
+/// Mask of all locking options;
+#define SSX_FILE_OP_LOCK_OPTIONS 0x7
+
+/// The FILE has a character pushed back by ungetc()
+#define SSX_FILE_HAS_CHARACTER 0xf
+
+/// All valid flags
+#define SSX_FILE_VALID_FLAGS 0xf
+
+/// @}
+
+
+extern FILE* stdin;
+extern FILE* stdout;
+extern FILE* stderr;
+
+/// SSX kernel output stream
+///
+/// This stream implements the printk() API. It must be a non-blocking stream
+/// so that it can be used in interrupt contexts.
+
+extern FILE* ssxout;
+
+extern FILE* ssxnull;
+
+int
+FILE_create(FILE* stream, int flags);
+
+int
+sread(FILE* stream, void* buf, size_t count, size_t* read);
+
+int
+swrite(FILE* stream, const void* buf, size_t count, size_t* written);
+
+int
+fflush(FILE* stream);
+
+int
+vfprintf(FILE* stream, const char* format, va_list argp)
+__attribute__ ((format (printf, 2, 0)));
+
+int
+vprintf(const char* format, va_list argp)
+__attribute__ ((format (printf, 1, 0)));
+
+int
+fprintf(FILE* stream, const char* fmt, ...)
+__attribute__ ((format (printf, 2, 3)));
+
+int
+printf(const char* fmt, ...) __attribute__ ((format (printf, 1, 2)));
+
+int
+printk(const char* fmt, ...) __attribute__ ((format (printf, 1, 2)));
+
+int
+vsprintf(char* str, const char* format, va_list argp)
+__attribute__ ((format (printf, 2, 0)));
+
+int
+sprintf(char* str, const char* format, ...)
+__attribute__ ((format (printf, 2, 3)));
+
+int
+vsnprintf(char* str, size_t size, const char* format, va_list argp)
+__attribute__ ((format (printf, 3, 0)));
+
+int
+snprintf(char* str, size_t size, const char* format, ...)
+__attribute__ ((format (printf, 3, 4)));
+
+int
+fputc(int c, FILE* stream);
+
+int
+fputs(const char* s, FILE* stream);
+
+int
+puts(const char* s);
+
+int
+putchar(int c);
+
+int
+fgetc(FILE* stream);
+
+int
+ungetc(int c, FILE* stream);
+
+size_t
+flines(FILE* stream);
+
+int
+ssx_io_error_set(FILE* stream, int code);
+
+/// Handle I/O errors including panic configurations
+#define SSX_IO_ERROR_IF(stream, condition, code) \
+ do { \
+ if (condition) { \
+ if (ssx_io_error_set(stream, code) && SSX_ERROR_PANIC) { \
+ SSX_PANIC(code); \
+ } else { \
+ return -(code); \
+ } \
+ } \
+ } while (0)
+
+#define SSX_IO_ERROR(stream, code) SSX_IO_ERROR_IF((stream), 1, (code))
+
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* !defined(_STDIO_H) && !defined(_UNISTD_H) */
+
+#endif /* __SSX_IO_H__ */
diff --git a/import/chips/p9/common/pmlib/ppc405lib/stdlib.c b/import/chips/p9/common/pmlib/ppc405lib/stdlib.c
new file mode 100644
index 00000000..3242cda4
--- /dev/null
+++ b/import/chips/p9/common/pmlib/ppc405lib/stdlib.c
@@ -0,0 +1,115 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/common/pmlib/ppc405lib/stdlib.c $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2015,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: stdlib.c,v 1.1.1.1 2013/12/11 20:49:20 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/stdlib.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file stdlib.c
+/// \brief Functions from <stdlib.h>
+///
+/// \note The strtoX() APIs are defined in strtox.[ch]
+
+#include "ssx.h"
+#include "ctype.h"
+#include "libssx.h"
+#include <stdlib.h>
+
+
+/// Convert a string to a long integer - base 10 only
+///
+/// atol(str) is defined here as strtol(str, 0, 10) in sympathy with the POSIX
+/// standard. Note that by specification "atol() does not detect
+/// errors", however here it will behave the same as the strtol() call just
+/// mentioned.
+
+long
+atol(const char* str)
+{
+ return strtol(str, 0, 10);
+}
+
+
+/// Convert a string to an integer - base 10 only
+///
+/// atoi(str) is defined here as strtol(str, 0, 10) in sympathy with the POSIX
+/// standard. Note that by specification "atoi() does not detect errors",
+/// however in this implementation the long integer returned by the strtol()
+/// call just mentioned is simply converted to an int.
+
+int
+atoi(const char* str)
+{
+ return strtol(str, 0, 10);
+}
+
+
+/// 'Exit' an application
+///
+/// An SSX application can not really 'exit'. By convention, exit(0) is the
+/// same as ssx_halt(). Calling exit() with a non-zero code causes a kernel
+/// panic - the exit code will be found in R3 on PowerPC.
+///
+/// Note that to exit a thread, the thread can either return from the thread
+/// entry routine or explicitly call ssx_complete(). exit() was implemented
+/// to allow porting of the EEMBC benchmarks.
+
+void
+exit(int status)
+{
+ if (status)
+ {
+ SSX_PANIC(ERROR_EXIT);
+ }
+
+ ssx_halt();
+}
+
+
+/// Compute the absolute value of the integer argument
+int
+abs(int i)
+{
+ return ((i < 0) ? -i : i);
+}
+
+
+/// Compute the absolute value of the long integer argument
+long int
+labs(long int i)
+{
+ return ((i < 0) ? -i : i);
+}
+
+
+/// Compute the absolute value of the long long integer argument
+long long int
+llabs(long long int i)
+{
+ return ((i < 0) ? -i : i);
+}
diff --git a/import/chips/p9/common/pmlib/ppc405lib/strcasecmp.c b/import/chips/p9/common/pmlib/ppc405lib/strcasecmp.c
new file mode 100644
index 00000000..59c94183
--- /dev/null
+++ b/import/chips/p9/common/pmlib/ppc405lib/strcasecmp.c
@@ -0,0 +1,102 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/common/pmlib/ppc405lib/strcasecmp.c $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2015,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: strcasecmp.c,v 1.1.1.1 2013/12/11 20:49:20 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/strcasecmp.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file strcasecmp.c
+/// \brief Implementation of strcasecmp() and strncasecmp()
+///
+/// These routines are rarely used, hence broken out into a separate file to
+/// save code space for most applications.
+
+#include "ssx.h"
+#include "string.h"
+
+/// Compare two strings ignoring case
+///
+/// The strcasecmp() function compares the two strings \a s1 and \a s2,
+/// ignoring the case of the characters. It returns an integer less than,
+/// equal to, or greater than zero if \a s1 is found, respectively, to be less
+/// than, to match, or be greater than \a s2.
+
+int
+strcasecmp(const char* s1, const char* s2)
+{
+ int rc;
+
+ if (s1 == s2)
+ {
+ rc = 0;
+ }
+ else
+ {
+ while(*s1 && (tolower(*s1) == tolower(*s2)))
+ {
+ s1++;
+ s2++;
+ }
+
+ rc = *((unsigned char*)s1) - *((unsigned char*)s2);
+ }
+
+ return rc;
+}
+
+
+/// Compare a portion of two strings ignoring case
+///
+/// The strncmp() function compares at most the first \n characters of the two
+/// strings \a s1 and \a s2, ignoring the case of the characters. It returns
+/// an integer less than, equal to, or greater than zero if (the prefix of) \a
+/// s1 is found, respectively, to be less than, to match, or be greater than
+/// (the prefix of) \a s2.
+
+int
+strncasecmp(const char* s1, const char* s2, size_t n)
+{
+ int rc;
+
+ if ((s1 == s2) || (n == 0))
+ {
+ rc = 0;
+ }
+ else
+ {
+ while(*s1 && (tolower(*s1) == tolower(*s2)) && n--)
+ {
+ s1++;
+ s2++;
+ }
+
+ rc = *((unsigned char*)s1) - *((unsigned char*)s2);
+ }
+
+ return rc;
+}
diff --git a/import/chips/p9/common/pmlib/ppc405lib/strdup.c b/import/chips/p9/common/pmlib/ppc405lib/strdup.c
new file mode 100644
index 00000000..996c7c99
--- /dev/null
+++ b/import/chips/p9/common/pmlib/ppc405lib/strdup.c
@@ -0,0 +1,66 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/common/pmlib/ppc405lib/strdup.c $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2015,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: strdup.c,v 1.1.1.1 2013/12/11 20:49:20 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/strdup.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file strdup.c
+/// \brief Functions from <string.h> that require malloc()
+///
+/// These APIs are split from string.c for the benefit of applications like
+/// OCC FW that don't use malloc().
+
+#include <stdlib.h>
+#include <string.h>
+
+/// Duplicate a string
+///
+/// \param s The string to duplicate
+///
+/// The strdup() function returns a pointer to a new string which is a
+/// duplicate of the input string \a s. Memory for the new string is obtained
+/// with malloc(), and can be freed with free().
+///
+/// \returns The strdup() function returns a pointer to the duplicated string,
+/// or NULL (0) if insufficient memory was available.
+
+char*
+strdup(const char* s)
+{
+ char* dup;
+
+ dup = (char*)malloc(strlen(s) + 1);
+
+ if (dup != 0)
+ {
+ strcpy(dup, s);
+ }
+
+ return dup;
+}
diff --git a/import/chips/p9/common/pmlib/ppc405lib/string_stream.c b/import/chips/p9/common/pmlib/ppc405lib/string_stream.c
new file mode 100644
index 00000000..6bbf9b43
--- /dev/null
+++ b/import/chips/p9/common/pmlib/ppc405lib/string_stream.c
@@ -0,0 +1,477 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/common/pmlib/ppc405lib/string_stream.c $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2015,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: string_stream.c,v 1.2 2014/02/03 01:30:25 daviddu Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/string_stream.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file string_stream.c
+/// \brief Implementations of string streams.
+///
+/// \bug Need to work out overwrite/multiple-write protection.
+
+#include "ssx.h"
+#include "string_stream.h"
+
+
+// 'Flush' a string stream by making it empty
+
+static int
+string_stream_fflush(FILE* stream)
+{
+ StringStream* string = (StringStream*) stream;
+
+ string->next_read = 0;
+ string->next_write = 0;
+ string->flags &= ~STRING_STREAM_FULL;
+ return 0;
+}
+
+
+// Read the remaining tail (if any) of the circular buffer, assuming the
+// buffer is not empty.
+
+static size_t
+read_tail(StringStream* string, void* buf, size_t size)
+{
+ size_t read, remainder;
+
+ read = 0;
+
+ if (string->next_read >= string->next_write)
+ {
+
+ remainder = string->size - string->next_read;
+ read = MIN(size, remainder);
+ memcpy(buf, (void*)(&(string->data[string->next_read])), read);
+
+ if (read != remainder)
+ {
+ string->next_read += read;
+ }
+ else
+ {
+ string->next_read = 0;
+ }
+ }
+
+ return read;
+}
+
+
+// Read the area (if any) from the read pointer to the write pointer
+
+static size_t
+read_head(StringStream* string, void* buf, size_t size)
+{
+ size_t read, remainder;
+
+ read = 0;
+
+ if (string->next_write > string->next_read)
+ {
+
+ remainder = string->next_write - string->next_read;
+ read = MIN(size, remainder);
+ memcpy(buf, (void*)(&(string->data[string->next_read])), read);
+ string->next_read += read;
+ }
+
+ return read;
+}
+
+
+// Read as much data as possible from a circular buffer. Return -EAGAIN if the
+// buffer would underflow.
+
+static int
+string_stream_sread(FILE* stream, void* buf, size_t size, size_t* read)
+{
+ StringStream* string = (StringStream*)stream;
+ size_t were_read;
+ int rc;
+
+ if ((string->next_read == string->next_write) &&
+ !(string->flags & STRING_STREAM_FULL))
+ {
+ were_read = 0;
+ }
+ else
+ {
+ were_read = read_tail(string, buf, size);
+
+ if (were_read != size)
+ {
+ were_read += read_head(string, buf + were_read, size - were_read);
+ }
+ }
+
+ if (were_read != 0)
+ {
+ string->flags &= ~STRING_STREAM_FULL;
+ }
+
+ *read = were_read;
+
+ if (were_read < size)
+ {
+ rc = -EAGAIN;
+ }
+ else
+ {
+ rc = 0;
+ }
+
+ return rc;
+}
+
+
+
+
+// Write the remaining tail (if any) of the circular buffer, assuming the
+// buffer is not full.
+
+static size_t
+write_tail(StringStream* string, const void* buf, size_t size)
+{
+ size_t written, remainder;
+
+ written = 0;
+
+ if (string->next_write >= string->next_read)
+ {
+
+ remainder = string->size - string->next_write; // string->size is the size of the stream(our buffer)
+ written = MIN(size, remainder);
+ // memcpy(void *dest, const void *src, size_t n) from /lib/memcpy.c
+ memcpy((void*)(&(string->data[string->next_write])), buf, written);
+
+ if (written != remainder)
+ {
+ string->next_write += written;
+ }
+ else
+ {
+ string->next_write = 0;
+ }
+ }
+
+ return written;
+}
+
+// Write the area (if any) from the write pointer to the read pointer
+
+static size_t
+write_head(StringStream* string, const void* buf, size_t size)
+{
+ size_t written, remainder;
+
+ written = 0;
+
+ if (string->next_read > string->next_write)
+ {
+
+ remainder = string->next_read - string->next_write;
+ written = MIN(size, remainder);
+ memcpy((void*)(&(string->data[string->next_write])), buf, written);
+ string->next_write += written;
+ }
+
+ return written;
+}
+
+
+// Write as much data as possible to a circular buffer. Return -EAGAIN if the
+// buffer would overflow.
+
+static int
+circular_swrite(FILE* stream, const void* buf, size_t size, size_t* written)
+{
+ StringStream* string = (StringStream*)stream;
+ size_t wrote;
+ int rc;
+
+ if (string->flags & STRING_STREAM_FULL)
+ {
+ wrote = 0;
+ }
+ else
+ {
+ wrote = write_tail(string, buf, size);
+
+ if (wrote != size)
+ {
+ wrote += write_head(string, buf + wrote, size - wrote);
+ }
+ }
+
+ if ((wrote != 0) && (string->next_read == string->next_write))
+ {
+ string->flags |= STRING_STREAM_FULL;
+ }
+
+ *written = wrote;
+
+ if (wrote < size)
+ {
+ rc = -EAGAIN;
+ }
+ else
+ {
+ rc = 0;
+ }
+
+ return rc;
+}
+
+
+// Effectively write all data to a circular buffer with wrapping semantics.
+
+static int
+wrapping_swrite(FILE* stream, const void* buf, size_t size, size_t* written)
+{
+ StringStream* string = (StringStream*)stream;
+ size_t wrote;
+ int rc;
+
+ if (size >= string->size) // If size of data >= size of buffer
+ {
+
+ // If the amount of data will fill or overflow the entire buffer size
+ // then we effectively fill the buffer with the final bytes of data.
+
+ string->next_read = 0;
+ string->next_write = 0;
+ string->flags |= STRING_STREAM_FULL;
+ memcpy((void*)string->data, buf + (size - string->size), size);
+
+ }
+ else
+ {
+
+ // If the string is not full, try to fill it with the
+ // circular_swrite().
+
+ if (string->flags & STRING_STREAM_FULL)
+ {
+ wrote = 0;
+ rc = -EAGAIN;
+ }
+ else
+ {
+ rc = circular_swrite(stream, buf, size, &wrote);
+ }
+
+ if (rc)
+ {
+
+ // The string is full and we need to overflow. We know that size
+ // is less than the buffer size, and the next_read == next_write.
+ // Mark the stream not full so a new circular write will work, and
+ // at the end reset the full condition.
+
+ string->flags &= ~STRING_STREAM_FULL;
+ rc = circular_swrite(stream, buf + wrote, size - wrote, &wrote);
+
+ if (rc)
+ {
+ SSX_PANIC(STRING_STREAM_BUG);
+ }
+
+ string->next_read = string->next_write;
+ string->flags |= STRING_STREAM_FULL;
+ }
+ }
+
+ *written = size;
+ return 0;
+}
+
+
+static int
+linear_swrite(FILE* stream, const void* buf, size_t size, size_t* written)
+{
+ // buf and size correspond to the data we are passing to our own buffer
+ uint32_t bit_0_mask = 0x80000000;
+ StringStream* string = (StringStream*)stream;
+ size_t wrote = 0; // right aligned
+ // int rc;
+ uint32_t num_bytes_written;
+ // uint32_t register_contents;
+
+
+ //if (wrote != size) {
+ // register_contents = in32(PMC_PORE_SCRATCH_REG1);
+ // register_contents = register_contents & bit_0_mask;
+
+ //if (!register_contents) {
+ // Before writing to SRAM, flush everything so it will write to the top
+ // of the buffer each time
+ string_stream_fflush(stream);
+
+ // Write printk statement to SRAM
+ // wrote will contain the number of bytes written
+
+ wrote += write_tail(string, buf + wrote, size - wrote);
+ // if wrote != size, tell Tcl to read the whole buffer, When Tcl is done loop back to write_tail
+ // buf= buf+wrote
+ // size= size - wrote
+ // continue loop until size = 0
+
+ // Sync
+ eieio();
+
+ // Store "wrote" to register
+ // Set bit 0 to 1
+ // out32(addr, data)
+ num_bytes_written = (uint32_t)wrote | bit_0_mask;
+ out32( PMC_PORE_SCRATCH_REG1 , num_bytes_written );
+
+ // Sync
+ eieio();
+ //}
+ //}
+
+ // outside of loop, set *written = wrote (which is equal to size once all data has been copied to our buffer)
+ *written = wrote;
+ return 0;
+
+}
+
+
+int
+_string_stream_create(StringStream* stream,
+ void* buf, size_t size, int flags,
+ int (*swrite)(FILE* stream,
+ const void* buf,
+ size_t size,
+ size_t* written))
+{
+ FILE* file = (FILE*)stream;
+ int rc;
+
+ if (SSX_ERROR_CHECK_API)
+ {
+ SSX_ERROR_IF((stream == 0) ||
+ ((buf == 0) && (size != 0)),
+ STRING_STREAM_INVALID_ARGUMENT);
+ }
+
+ rc = FILE_create(file, flags);
+
+ if (!rc)
+ {
+ file->swrite = swrite;
+ file->sread = string_stream_sread;
+ file->fflush = string_stream_fflush;
+ stream->data = buf;
+ stream->size = size;
+ stream->next_read = 0;
+ stream->next_write = 0;
+ stream->flags = 0;
+ }
+
+ return rc;
+}
+
+
+int
+circular_stream_create(CircularStream* stream,
+ void* buf, size_t size, int flags)
+{
+ return _string_stream_create(stream, buf, size, flags, circular_swrite);
+}
+
+
+int
+wrapping_stream_create(CircularStream* stream,
+ void* buf, size_t size, int flags)
+{
+ return _string_stream_create(stream, buf, size, flags, wrapping_swrite);
+}
+
+
+int
+linear_stream_create(CircularStream* stream,
+ void* buf, size_t size, int flags)
+{
+ FILE* file = (FILE*)stream;
+ int rc;
+
+ rc = _string_stream_create(stream, buf, size, flags, linear_swrite);
+
+ if (!rc)
+ {
+
+ file->sread = NULL;
+ // Write to register where location of buffer is
+ out32( PMC_PORE_SCRATCH_REG1, (uint32_t)buf);
+ }
+
+ return rc;
+}
+
+
+// InputStream uses string_stream_sread(), however returns EOF once all data
+// has been read.
+
+static int
+input_stream_sread(FILE* stream, void* buf, size_t size, size_t* read)
+{
+ int rc;
+
+ rc = string_stream_sread(stream, buf, size, read);
+
+ if (rc == -EAGAIN)
+ {
+ rc = EOF;
+ }
+
+ return rc;
+}
+
+
+// For simplicity (and ease of maintainence) we create a normal string stream
+// then overwrite a few key fields.
+
+int
+input_stream_create(StringStream* stream, void* buf, size_t size, int flags)
+{
+ int rc;
+
+ rc = _string_stream_create(stream, buf, size, flags, 0);
+
+ if (!rc)
+ {
+ stream->stream.sread = input_stream_sread;
+ stream->stream.fflush = 0;
+ stream->flags = STRING_STREAM_FULL;
+ }
+
+ return rc;
+}
diff --git a/import/chips/p9/common/pmlib/ppc405lib/string_stream.h b/import/chips/p9/common/pmlib/ppc405lib/string_stream.h
new file mode 100644
index 00000000..07658153
--- /dev/null
+++ b/import/chips/p9/common/pmlib/ppc405lib/string_stream.h
@@ -0,0 +1,278 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/common/pmlib/ppc405lib/string_stream.h $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2015,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __STRING_STREAM_H__
+#define __STRING_STREAM_H__
+
+// $Id: string_stream.h,v 1.2 2014/02/03 01:30:25 daviddu Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/string_stream.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file string_stream.h
+/// \brief Implementations of string streams.
+
+#include "ssx_io.h"
+
+/// A string stream
+///
+/// This structure is used for the public CircularStream and WrappingStream
+/// types, as well as for the library-internal types used to implement
+/// sprintf() and snprintf().
+
+typedef struct
+{
+
+ /// The base class
+ FILE stream;
+
+ /// Data storage - provided by the creator
+ uint8_t* data;
+
+ /// The size of the data storage
+ size_t size;
+
+ /// The index of the next byte to write
+ size_t next_write;
+
+ /// The index of the next byte to read
+ size_t next_read;
+
+ /// Stream flags, see \ref string_stream_flags
+ int flags;
+
+} StringStream;
+
+
+/// A StringStream with circular buffer semantics
+///
+/// The swrite() method copies the input data to the stream buffer, which is
+/// treated as a circular buffer. If the swrite() would overflow the buffer,
+/// then as much data as possible is written and swrite returns -EAGAIN. In
+/// all cases swrite() returns the number of bytes actually written to the
+/// buffer.
+///
+/// The sread() method copies data from the StringStream circular buffer to
+/// the caller's buffer until either the caller's request is satisfied or all
+/// of the immediately available data has been read from the buffer. If the
+/// caller's request can not be immediately granted then as much data as
+/// possible is copied and sread() returns -EAGAIN. In all cases sread()
+/// returns the number of bytes actually read from the buffer.
+///
+/// The fflush() method marks the buffer as empty, effectively losing any data
+/// currently stored in the buffer.
+
+typedef StringStream CircularStream;
+
+
+/// A StringStream with wrapping circular buffer semantics
+///
+/// The swrite() method copies the input data to the stream buffer, which is
+/// treated as a circular buffer. If the swrite() would overflow the buffer,
+/// then unread data is overwritten with new data. If the size of the
+/// swrite() exceeds the buffer length then the effect is simply to fill the
+/// buffer with the final bytes of the caller's data. swrite() always returns
+/// the number of bytes requested to be written.
+///
+/// The sread() method copies data from the StringStream circular buffer to
+/// the caller's buffer until either the caller's request is satisfied or all
+/// of the immediately available data has been read from the buffer. If the
+/// caller's request can not be immediately granted then as much data as
+/// possible is copied and sread() returns -EAGAIN. In all cases sread()
+/// returns the number of bytes actually read from the buffer.
+///
+/// The fflush() method marks the buffer as empty, effectively losing any data
+/// currently stored in the buffer.
+
+typedef StringStream WrappingStream;
+
+
+/// Create a StringStream
+///
+/// \param stream The StringStream to initialize
+///
+/// \param buf The stream data buffer
+///
+/// \param size The size of the data buffer in bytes
+///
+/// \param flags Flags for FILE_create()
+///
+/// \param swrite The function to be installed as the swrite() function for
+/// the underlying FILE object. The sread() and fflush() functions are fixed.
+///
+/// This API initializes a StringStream structure for use in I/O operations.
+/// This API will typically only be used by the creation functions of specific
+/// StringStream types.
+///
+/// \retval 0 Success
+///
+/// \retval -STRING_STREAM_INVALID_ARGUMENT Either \a stream is NULL (0)
+/// or \a buf is NULL(0) and \a size is non-0.
+
+int
+_string_stream_create(StringStream* stream,
+ void* buf, size_t size, int flags,
+ int (*swrite)(FILE* stream,
+ const void* buf,
+ size_t size,
+ size_t* written));
+
+/// Create a CircularStream
+///
+/// \param stream The CircularStream to initialize
+///
+/// \param buf The stream data buffer
+///
+/// \param size The size of the data buffer in bytes
+///
+/// \param flags Flags for FILE_create()
+///
+/// This API initializes a CircularStream structure for use in I/O
+/// operations. Once created, the pointer to the CircularStream stream can be
+/// cast to a FILE* and used for sread(), swrite(), fflush() and fprintf()
+/// operations.
+///
+/// \retval 0 Success
+///
+/// \retval -STRING_STREAM_INVALID_ARGUMENT Either \a stream is NULL (0)
+/// or \a buf is NULL(0) and \a size is non-0.
+
+int
+circular_stream_create(CircularStream* stream,
+ void* buf, size_t size, int flags);
+
+
+/// Create a WrappingStream
+///
+/// \param stream The WrappingStream to initialize
+///
+/// \param buf The stream data buffer
+///
+/// \param size The size of the data buffer in bytes
+///
+/// \param flags Flags for FILE_create()
+///
+/// This API initializes a WrappingStream structure for use in I/O
+/// operations. Once created, the pointer to the WrappingStream stream can be
+/// cast to a FILE* and used for sread(), swrite(), fflush() and fprintf()
+/// operations.
+///
+/// \retval 0 Success
+///
+/// \retval -STRING_STREAM_INVALID_ARGUMENT Either \a stream is NULL (0)
+/// or \a buf is NULL(0) and \a size is non-0.
+
+int
+wrapping_stream_create(CircularStream* stream,
+ void* buf, size_t size, int flags);
+
+
+/// Create a LinearStream
+///
+/// \param stream The LinearStream to initialize
+///
+/// \param buf The stream data buffer
+///
+/// \param size The size of the data buffer in bytes
+///
+/// \param flags Flags for FILE_create()
+///
+/// This API initializes a LinearStream structure for use in I/O
+/// operations. Once created, the pointer to the WrappingStream stream can be
+/// cast to a FILE* and used for sread(), swrite(), fflush() and fprintf()
+/// operations.
+///
+/// \retval 0 Success
+///
+/// \retval -STRING_STREAM_INVALID_ARGUMENT Either \a stream is NULL (0)
+/// or \a buf is NULL(0) and \a size is non-0.
+
+
+int
+linear_stream_create(CircularStream* stream,
+ void* buf, size_t size, int flags);
+
+
+/// A StringStream used as a read-only input stream
+///
+/// This is a CircualarStream created with a full buffer and without a write
+/// method. It uses a special read method that returns EOF once the buffer is
+/// empty rather than -EAGAIN.
+
+typedef StringStream InputStream;
+
+
+/// Create an InputStream
+///
+/// \param stream The InputStream to initialize
+///
+/// \param buf The stream data buffer.
+///
+/// \param size The size of the readable portion of the data buffer in bytes
+///
+/// \param flags Flags for FILE_create()
+///
+/// This API initializes an InputStream structure for use in input operations.
+/// The stream data buffer contains \a size bytes of data which can be read.
+/// Once created, the pointer to the InputStream stream can be cast to a FILE*
+/// and used for sread(), fgetc() and ungetc() operations. Neither fflush()
+/// nor swrite() are supported on this class of stream. The read operations
+/// will succeed until \a size bytes have been returned from the stream, at
+/// which point the stream will return EOF on any subsequent reads.
+///
+/// \retval 0 Success
+///
+/// \retval -STRING_STREAM_INVALID_ARGUMENT Either \a stream is NULL (0)
+/// or \a buf is NULL(0) and \a size is non-0.
+
+int
+input_stream_create(InputStream* stream,
+ void* buf, size_t size, int flags);
+
+
+/// \defgroup string_stream_flags StringStream Flags
+///
+/// @{
+
+/// The StringStream is full
+#define STRING_STREAM_FULL 0x1
+
+/// @}
+
+
+/// \defgroup string_stream_codes StringStream Error/Panic Codes
+///
+/// @{
+
+/// A bug was detected in a StringStream function
+#define STRING_STREAM_BUG 0x00787701
+#define STRING_STREAM_INVALID_ARGUMENT 0x00787702
+
+/// @}
+
+
+#endif // __STRING_STREAM_H__
diff --git a/import/chips/p9/common/pmlib/ppc405lib/strtox.c b/import/chips/p9/common/pmlib/ppc405lib/strtox.c
new file mode 100644
index 00000000..507c913d
--- /dev/null
+++ b/import/chips/p9/common/pmlib/ppc405lib/strtox.c
@@ -0,0 +1,726 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/common/pmlib/ppc405lib/strtox.c $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2015,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: strtox.c,v 1.2 2014/02/03 01:30:25 daviddu Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/strtox.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file strtox.c
+/// \brief Implementation of strtol(), strtoul(), strtoll() and strtoull()
+///
+/// <b> Standard String Conversion Routines </b>
+///
+/// This file contains implementaions of strtol(), strtoul(), strtoll() and
+/// strtoull(). These APIs are all called as
+///
+/// \code
+/// strtoX(const char* str, char** endptr, int base)
+/// \endcode
+///
+/// where X is
+///
+/// - l : Convert to a long integer
+/// - ul : Convert to an unsigned long integer
+/// - ll : Convert to a long long integer
+/// - ull : Convert to an unsigned long long integer
+///
+/// \param str The string to convert
+///
+/// \param endptr If non-null, will be set to a pointer to the portion of the
+/// string following the convertable portion. If no conversion is performed
+/// then the original \a str is returned here.
+///
+/// \param base Either 0 to indicate that the base should be derived from
+/// radix markers in the string, or a number in the range 2 to 36 inclusive.
+///
+/// The APIs convert the initial portion of the string pointed to by \a str to
+/// an integer, which is either a long integer (strtol), an unsigned long
+/// (strtoul()), a long long (strtoll), or an unsigned long long
+/// (strtoull). First, the APIs decompose the input string into three parts:
+///
+/// - An initial, possibly empty, sequence of white-space characters (as
+/// specified by isspace())
+///
+/// - A subject sequence interpreted as an integer represented in some radix
+/// determined by the value of \a base
+///
+/// - A final string of one or more unrecognized characters, including the
+/// terminating null byte of the input string.
+///
+/// The APIs then attempt to convert the subject sequence to an integer of the
+/// required type and returns the result.
+///
+/// If the value of \a base is 0, the expected form of the subject sequence is
+/// that of a decimal constant, octal constant, or hexadecimal constant, any
+/// of which may be preceded by a '+' or '-' sign. A decimal constant begins
+/// with a non-zero digit, and consists of a sequence of decimal digits. An
+/// octal constant consists of the prefix '0' optionally followed by a
+/// sequence of the digits '0' to '7' only. A hexadecimal constant consists of
+/// the prefix 0x or 0X followed by a sequence of the decimal digits and
+/// letters 'a' (or 'A' ) to 'f' (or 'F' ) with values 10 to 15 respectively.
+///
+/// If the value of \a base is between 2 and 36, the expected form of the
+/// subject sequence is a sequence of letters and digits representing an
+/// integer with the radix specified by base, optionally preceded by a '+' or
+/// '-' sign. The letters from 'a' (or 'A' ) to 'z' (or 'Z' ) inclusive are
+/// ascribed the values 10 to 35; only letters whose ascribed values are less
+/// than that of base are permitted. If the value of base is 16, the
+/// characters 0x or 0X may optionally precede the sequence of letters and
+/// digits, following the sign if present.
+///
+/// The subject sequence is defined as the longest initial subsequence of the
+/// input string, starting with the first non-white-space character that is of
+/// the expected form. The subject sequence contains no characters if the
+/// input string is empty or consists entirely of white-space characters, or if
+/// the first non-white-space character is other than a sign or a permissible
+/// letter or digit.
+///
+/// If the subject sequence has the expected form and the value of base is 0,
+/// the sequence of characters starting with the first digit will be
+/// interpreted as an integer constant. If the subject sequence has the
+/// expected form and the value of base is between 2 and 36, it will be used
+/// as the base for conversion, ascribing to each letter its value as given
+/// above. If the subject sequence begins with a minus sign, the value
+/// resulting from the conversion will be negated. A pointer to the final
+/// string will be stored in the object pointed to by \a endptr, provided that
+/// \a endptr is not a null pointer.
+///
+/// If the subject sequence is empty or does not have the expected form, no
+/// conversion is performed; the value of \a str is stored in the object
+/// pointed to by \a endptr, provided that \a endptr is not a null pointer.
+///
+/// Note that the unsigned APIs silently convert signed representations into
+/// the equivalent unsigned number.
+///
+/// Since 0, (L)LONG_MIN and (U)(L)LONG_MAX are returned on error and are
+/// also valid returns on success, there is no way for an SSX application to
+/// determine whether the conversion succeeded or failed (since SSX does not
+/// support \a errno). For this reason it is recommended that SSX-only
+/// applications use the underlying APIs _strtol(), _strtoul(), _strtoll() and
+/// _strtoull(), or even better the extended APIs strtoi32(), strtou32(),
+/// strtoi64() or strtou64() discussed further below.
+///
+/// Upon successful completion, strtoX() returns the converted
+/// value, if any. If no conversion could be performed or there was an error
+/// in the base specification, 0 is returned.
+///
+/// If the correct value is outside the range of representable values,
+/// (L)LONG_MIN or (U)(L)LONG_MAX will be returned (according to the sign
+/// and type of the value).
+///
+/// Note: This specification is adapted from IEEE Std. 10003.1, 2003 Edition
+///
+///
+/// <b> Underlying APIs </b>
+///
+/// The APIs underlying the standard APIs are all called as
+///
+/// \code
+/// int _strtoX(const char* str, char** endptr, int radix, <type>* value)
+/// \endcode
+///
+/// where X is
+///
+/// - l : Convert to a long integer
+/// - ul : Convert to an unsigned long integer
+/// - ll : Convert to a long long integer
+/// - ull : Convert to an unsigned long long integer
+///
+/// \param str The string to convert
+///
+/// \param endptr If non-null, will be set to a pointer to the portion of the
+/// string following the convertable portion. If no conversion is performed
+/// then the original \a str is returned here.
+///
+/// \param base Either 0 to indicate that the base should be derived from
+/// radix markers in the string, or a number in the range 2 to 36 inclusive.
+///
+/// \param value The converted value, returned as the return value of the
+/// standard API.
+///
+/// The return value of the underlying APIs is one of the following
+///
+/// \retval 0 Success
+///
+/// \retval -STRTOX_NO_CONVERSION_EMPTY No conversion was performed because the
+/// string was effectively empty.
+///
+/// \retval -STRTOX_NO_CONVERSION_PARSE No conversion was performed because the
+/// string did not parse as an integer.
+///
+/// \retval -STRTOX_INVALID_ARGUMENT No conversion was performed because the
+/// \a base specification was not valid.
+///
+/// \retval -STRTOX_UNDERFLOW_STRTOL1 Conversion resulted in underflow
+///
+/// \retval -STRTOX_UNDERFLOW_STRTOL2 Conversion resulted in underflow
+///
+/// \retval -STRTOX_UNDERFLOW_STRTOLL1 Conversion resulted in underflow
+///
+/// \retval -STRTOX_UNDERFLOW_STRTOLL2 Conversion resulted in underflow
+///
+/// \retval -STRTOX_OVERFLOW_STRTOL1 Conversion resulted in overflow
+///
+/// \retval -STRTOX_OVERFLOW_STRTOL2 Conversion resulted in overflow
+///
+/// \retval -STRTOX_OVERFLOW_STRTOLL1 Conversion resulted in overflow
+///
+/// \retval -STRTOX_OVERFLOW_STRTOLL2 Conversion resulted in overflow
+///
+///
+/// <b> Extended APIs </b>
+///
+/// The extended APIs are the preferred way to do portable integer
+/// conversion. These APIs are all called as
+///
+/// \code
+/// int strtoX(const char* str, char** endptr, int radix, <type>* value)
+/// \endcode
+///
+/// where X is
+///
+/// - i32 : Convert to an int32_t
+/// - u32 : Convert to a uint32_t
+/// - i64 : Convert to an int64_t
+/// - u64 : Convert to a uint64_t
+///
+/// \param str The string to convert
+///
+/// \param endptr If non-null, will be set to a pointer to the portion of the
+/// string following the convertable portion. If no conversion is performed
+/// then the original \a str is returned here.
+///
+/// \param base Either 0 to indicate that the base should be derived from
+/// radix markers in the string, or a number in the range 2 to 36 inclusive.
+///
+/// \param value The converted value
+///
+/// The return value of the underlying APIs is one of the following
+///
+/// \retval 0 Success
+///
+/// \retval -STRTOX_NO_CONVERSION_EMPTY No conversion was performed because the
+/// string was effectively empty.
+///
+/// \retval -STRTOX_NO_CONVERSION_PARSE No conversion was performed because the
+/// string did not parse as an integer.
+///
+/// \retval -STRTOX_INVALID_ARGUMENT No conversion was performed because the
+/// \a base specification was not valid.
+///
+/// \retval -STRTOX_UNDERFLOW_STRTOL1 Conversion resulted in underflow
+///
+/// \retval -STRTOX_UNDERFLOW_STRTOL2 Conversion resulted in underflow
+///
+/// \retval -STRTOX_UNDERFLOW_STRTOLL1 Conversion resulted in underflow
+///
+/// \retval -STRTOX_UNDERFLOW_STRTOLL2 Conversion resulted in underflow
+///
+/// \retval -STRTOX_OVERFLOW_STRTOL1 Conversion resulted in overflow
+///
+/// \retval -STRTOX_OVERFLOW_STRTOL2 Conversion resulted in overflow
+///
+/// \retval -STRTOX_OVERFLOW_STRTOLL1 Conversion resulted in overflow
+///
+/// \retval -STRTOX_OVERFLOW_STRTOLL2 Conversion resulted in overflow
+///
+
+#include "ssx.h"
+#include "ctype.h"
+#include "libssx.h"
+#include "strtox.h"
+
+
+// Skip whitespace
+
+static const char*
+skip_whitespace(const char* s)
+{
+ while (isspace(*s))
+ {
+ s++;
+ }
+
+ return s;
+}
+
+// Pick up a +/- sign. This is a predicate returning 1 if the value is
+// negated.
+
+static int
+sign(const char** s)
+{
+ if (**s == '+')
+ {
+ (*s)++;
+ return 0;
+ }
+ else if (**s == '-')
+ {
+ (*s)++;
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+
+// Look for a radix mark (0, 0[xX]). The string pointer is advanced if it is a
+// hex mark (0[xX]), but not for a simple '0' which could be either the start
+// of an octal constant or simply the number 0. The return value is either 8,
+// 10 or 16.
+
+static int
+radix_mark(const char** s)
+{
+ const char* p = *s;
+
+ if (p[0] == '0')
+ {
+ if ((p[1] == 'x') || (p[1] == 'X'))
+ {
+ *s += 2;
+ return 16;
+ }
+ else
+ {
+ return 8;
+ }
+ }
+ else
+ {
+ return 10;
+ }
+}
+
+
+// Parse a character as a radix-base digit. Return the value of the digit or
+// -1 if it is not a legal digit for the radix.
+
+static int
+parse_digit(char c, int radix)
+{
+ if (isdigit(c))
+ {
+ if ((c - '0') < radix)
+ {
+ return c - '0';
+ }
+ else
+ {
+ return -1;
+ }
+ }
+ else if (radix <= 10)
+ {
+ return -1;
+ }
+ else
+ {
+ if (islower(c))
+ {
+ if ((c - 'a') < (radix - 10))
+ {
+ return c - 'a' + 10;
+ }
+ else
+ {
+ return -1;
+ }
+ }
+ else if (isupper(c))
+ {
+ if ((c - 'A') < (radix - 10))
+ {
+ return c - 'A' + 10;
+ }
+ else
+ {
+ return -1;
+ }
+ }
+ else
+ {
+ return -1;
+ }
+ }
+}
+
+
+// The most basic API is strtox(), which converts a string to an unsigned long
+// long. All of the base APIs are written in terms of this. This is legal due
+// to the fact that conversion is defined to continue even in the event of
+// overflow. This API may return the codes STRTOX_NO_CONVERSION_EMPTY,
+// STRTOX_NO_CONVERSION_PARSE or STRTOX_INVALID_ARGUMENT,
+// which the standard APIs always convert to a 0
+// return value. Otherwise the flags 'overflow' and 'negative' are used by
+// the base APIs to determine how to handle special cases.
+
+static int
+strtox(const char* str, char** endptr, int base,
+ unsigned long long* value, int* negative, int* overflow)
+{
+ const char* s;
+ unsigned long long new;
+ int rc, radix, digit;
+
+
+ do
+ {
+
+ s = str;
+ *value = 0;
+ *negative = 0;
+ *overflow = 0;
+
+ // Initial error checks
+
+ if ((base != 0) && ((base < 2) || (base > 36)))
+ {
+ rc = STRTOX_INVALID_ARGUMENT;
+ break;
+ }
+
+ // Skip whitespace
+
+ s = skip_whitespace(s);
+
+ if (*s == '\0')
+ {
+ rc = STRTOX_NO_CONVERSION_EMPTY;
+ break;
+ }
+
+ // Process a +/- sign. Only one is allowed.
+
+ *negative = sign(&s);
+
+ // Look for a radix mark. Note that if base == 16 this will cause the
+ // skip of a leading 0 in the string not followed by [xX], but that's
+ // OK because it doesn't change the result of the conversion.
+
+ if (base == 0)
+ {
+ radix = radix_mark(&s);
+ }
+ else
+ {
+ radix = base;
+
+ if (radix == 16)
+ {
+ radix_mark(&s);
+ }
+ }
+
+ // Parse. Note that once overflow is detected we continue to parse
+ // (but ignore the data).
+
+ rc = STRTOX_NO_CONVERSION_PARSE;
+
+ while ((digit = parse_digit(*s, radix)) >= 0)
+ {
+ s++;
+
+ if (!*overflow)
+ {
+ rc = 0;
+ new = (*value * radix) + digit;
+
+ if (new < *value)
+ {
+ *overflow = 1;
+ }
+ else
+ {
+ *value = new;
+ }
+ }
+ }
+ }
+ while(0);
+
+ if (endptr)
+ {
+ if (rc == 0)
+ {
+ *endptr = (char*)s;
+ }
+ else
+ {
+ *endptr = (char*)str;
+ }
+ }
+
+ return rc;
+}
+
+
+/// See documentation for the file strtox.c
+int
+_strtol(const char* str, char** endptr, int base, long* value)
+{
+ int rc, negative, overflow;
+ unsigned long long value_ull;
+
+ rc = strtox(str, endptr, base, &value_ull, &negative, &overflow);
+
+ if (rc)
+ {
+ *value = 0;
+ }
+ else
+ {
+ if (overflow || (value_ull != (unsigned long)value_ull))
+ {
+ if (negative)
+ {
+ rc = STRTOX_UNDERFLOW_STRTOL1;
+ *value = LONG_MIN;
+ }
+ else
+ {
+ rc = STRTOX_OVERFLOW_STRTOL1;
+ *value = LONG_MAX;
+ }
+ }
+ else if (negative)
+ {
+ if (value_ull > ((unsigned long long)LONG_MAX + 1ull))
+ {
+ rc = STRTOX_UNDERFLOW_STRTOL2;
+ *value = LONG_MIN;
+ }
+ else
+ {
+ *value = ~value_ull + 1;
+ }
+ }
+ else if (value_ull > (unsigned long long)LONG_MAX)
+ {
+ rc = STRTOX_OVERFLOW_STRTOL2;
+ *value = LONG_MAX;
+ }
+ else
+ {
+ *value = value_ull;
+ }
+ }
+
+ return rc;
+}
+
+
+/// See documentation for the file strtox.c
+int
+_strtoll(const char* str, char** endptr, int base, long long* value)
+{
+ int rc, negative, overflow;
+ unsigned long long value_ull;
+
+ rc = strtox(str, endptr, base, &value_ull, &negative, &overflow);
+
+ if (rc)
+ {
+ *value = 0;
+ }
+ else
+ {
+ if (overflow)
+ {
+ if (negative)
+ {
+ rc = STRTOX_UNDERFLOW_STRTOLL1;
+ *value = LLONG_MIN;
+ }
+ else
+ {
+ rc = STRTOX_OVERFLOW_STRTOLL1;
+ *value = LLONG_MAX;
+ }
+ }
+ else if (negative)
+ {
+ if (value_ull > ((unsigned long long)LLONG_MAX + 1ull))
+ {
+ rc = STRTOX_UNDERFLOW_STRTOLL2;
+ *value = LLONG_MIN;
+ }
+ else
+ {
+ *value = ~value_ull + 1;
+ }
+ }
+ else if (value_ull > (unsigned long long)LLONG_MAX)
+ {
+ rc = STRTOX_OVERFLOW_STRTOLL2;
+ *value = LLONG_MAX;
+ }
+ else
+ {
+ *value = value_ull;
+ }
+ }
+
+ return rc;
+}
+
+
+/// See documentation for the file strtox.c
+int
+_strtoul(const char* str, char** endptr, int base, unsigned long* value)
+{
+ int rc, negative, overflow;
+ unsigned long long value_ull;
+
+ rc = strtox(str, endptr, base, &value_ull, &negative, &overflow);
+
+ if (rc)
+ {
+ *value = 0;
+ }
+ else
+ {
+ if (overflow || (value_ull != (unsigned long)value_ull))
+ {
+ rc = STRTOX_OVERFLOW_STRTOUL;
+ *value = ULONG_MAX;
+ }
+ else
+ {
+ *value = value_ull;
+
+ if (negative)
+ {
+ *value = ~*value + 1;
+ }
+ }
+ }
+
+ return rc;
+}
+
+/// See documentation for the file strtox.c
+int
+_strtoull(const char* str, char** endptr, int base, unsigned long long* value)
+{
+ int rc, negative, overflow;
+
+ rc = strtox(str, endptr, base, value, &negative, &overflow);
+
+ if (rc)
+ {
+ *value = 0;
+ }
+ else
+ {
+ if (overflow)
+ {
+ rc = STRTOX_OVERFLOW_STRTOULL;
+ *value = ULLONG_MAX;
+ }
+ else
+ {
+ if (negative)
+ {
+ *value = ~*value + 1;
+ }
+ }
+ }
+
+ return rc;
+}
+
+
+/// See documentation for the file strtox.c
+long int
+strtol(const char* str, char** endptr, int base)
+{
+ long int value;
+
+ _strtol(str, endptr, base, &value);
+ return value;
+}
+
+
+/// See documentation for the file strtox.c
+long long int
+strtoll(const char* str, char** endptr, int base)
+{
+ long long int value;
+
+ _strtoll(str, endptr, base, &value);
+ return value;
+}
+
+
+/// See documentation for the file strtox.c
+unsigned long int
+strtoul(const char* str, char** endptr, int base)
+{
+ unsigned long int value;
+
+ _strtoul(str, endptr, base, &value);
+ return value;
+}
+
+
+/// See documentation for the file strtox.c
+unsigned long long int
+strtoull(const char* str, char** endptr, int base)
+{
+ unsigned long long int value;
+
+ _strtoull(str, endptr, base, &value);
+ return value;
+}
+
+
+#if (__GNUC__ < 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ <= 1))
+
+/// Internal version of strtol()
+///
+/// ppcnf-mcp5 (GCC 4.1) requires that the entry point __strtol_internal() be
+/// present at certain optimization levels. This is equivalent to strtol()
+/// except that it takes an extra argument that must be == 0. The \a group
+/// parameter is supposed to control locale-specific thousands grouping.
+
+long int
+__strtol_internal(const char* str, char** endptr, int base, int group)
+{
+ if (group != 0)
+ {
+ SSX_PANIC(STRTOX_INVALID_ARGUMENT_STRTOL);
+ }
+
+ return strtol(str, endptr, base);
+}
+
+#endif
diff --git a/import/chips/p9/common/pmlib/ppc405lib/strtox.h b/import/chips/p9/common/pmlib/ppc405lib/strtox.h
new file mode 100644
index 00000000..fd154813
--- /dev/null
+++ b/import/chips/p9/common/pmlib/ppc405lib/strtox.h
@@ -0,0 +1,151 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/common/pmlib/ppc405lib/strtox.h $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2015,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __STRTOX_H__
+#define __STRTOX_H__
+
+// $Id: strtox.h,v 1.2 2014/02/03 01:30:25 daviddu Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/strtox.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file strtox.h
+/// \brief Underlying and extended APIs that support strtoX macros
+///
+/// See the Doxygen comments of the file strtox.c for descriptions of the
+/// facilities provided by this header.
+
+#ifndef __ASSEMBLER__
+
+#include <limits.h>
+
+// Error codes
+
+#define STRTOX_NO_CONVERSION_EMPTY 0x00787901
+#define STRTOX_NO_CONVERSION_PARSE 0x00787902
+#define STRTOX_INVALID_ARGUMENT 0x00787903
+#define STRTOX_INVALID_ARGUMENT_STRTOL 0x00787904
+#define STRTOX_UNDERFLOW_STRTOL1 0x00787905
+#define STRTOX_UNDERFLOW_STRTOL2 0x00787906
+#define STRTOX_UNDERFLOW_STRTOLL1 0x00787907
+#define STRTOX_UNDERFLOW_STRTOLL2 0x00787908
+#define STRTOX_OVERFLOW_STRTOL1 0x00787909
+#define STRTOX_OVERFLOW_STRTOL2 0x0078790a
+#define STRTOX_OVERFLOW_STRTOLL1 0x0078790b
+#define STRTOX_OVERFLOW_STRTOLL2 0x0078790c
+#define STRTOX_OVERFLOW_STRTOUL 0x0078790d
+#define STRTOX_OVERFLOW_STRTOULL 0x0078790e
+
+// Earlier GCC configurations (ppcnf-mcp5-gcc) are not configured to define
+// these standard constants, which exist in the include tree under various
+// switches and configuration settings (from <limits.h>). They are defined by
+// default in later standard cross builds however (GCC 4.5, 4.6). However we
+// always assume that (long long) is a 64-bit type. It's likely that this is
+// the only place these constant will be used (as they are defined as the
+// values for under/overflow of strtoX() conversions), however it may be
+// necessary in the future to move these #defines somewhere else.
+
+#ifndef LLONG_MIN
+ #define LLONG_MIN (0x8000000000000000ll)
+#endif
+
+#ifndef LLONG_MAX
+ #define LLONG_MAX (0x7fffffffffffffffll)
+#endif
+
+#ifndef ULLONG_MAX
+ #define ULLONG_MAX (0xffffffffffffffffull)
+#endif
+
+int
+_strtol(const char* str, char** endptr, int base, long* value);
+
+int
+_strtoul(const char* str, char** endptr, int base, unsigned long* value);
+
+int
+_strtoll(const char* str, char** endptr, int base, long long* value);
+
+int
+_strtoull(const char* str, char** endptr, int base, unsigned long long* value);
+
+
+// The way the sizeof(long) is discovered by default depends on which version
+// of gcc/cpp we're using as these macros are predefined by cpp.
+
+#if (__SIZEOF_LONG__ == 4) || (__LONG_MAX__ == 2147483647L)
+
+/// See documentation for the file strtox.c
+static inline int
+strtoi32(const char* str, char** endptr, int base, int32_t* value)
+{
+ long int value_l;
+ int rc;
+
+ rc = _strtol(str, endptr, base, &value_l);
+ *value = value_l;
+ return rc;
+}
+
+/// See documentation for the file strtox.c
+static inline int
+strtou32(const char* str, char** endptr, int base, uint32_t* value)
+{
+ unsigned long int value_ul;
+ int rc;
+
+ rc = _strtoul(str, endptr, base, &value_ul);
+ *value = value_ul;
+ return rc;
+}
+
+#else
+
+#error "No port of strtox.h yet for systems with sizeof(long) != 4"
+
+#endif
+
+// It is assumed that long long is always 64 bits; There is no standard macro
+// for this size constant
+
+/// See documentation for the file strtox.c
+static inline int
+strtoi64(const char* str, char** endptr, int base, int64_t* value)
+{
+ return _strtoll(str, endptr, base, value);
+}
+
+/// See documentation for the file strtox.c
+static inline int
+strtou64(const char* str, char** endptr, int base, uint64_t* value)
+{
+ return _strtoull(str, endptr, base, value);
+}
+
+#endif // __ASSEMBLER__
+
+#endif // __STRTOX_H__
diff --git a/import/chips/p9/common/pmlib/ppc405lib/time.c b/import/chips/p9/common/pmlib/ppc405lib/time.c
new file mode 100644
index 00000000..4ff2cca3
--- /dev/null
+++ b/import/chips/p9/common/pmlib/ppc405lib/time.c
@@ -0,0 +1,85 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/common/pmlib/ppc405lib/time.c $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2015,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: time.c,v 1.1.1.1 2013/12/11 20:49:20 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/time.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file time.c
+/// \brief Implementation of functions from <time.h>
+///
+/// The following standard APIs are currently supported:
+///
+/// - clock_gettime() with the single clock id CLOCK_REALTIME
+///
+/// Since SSX does not currently have any per-thread CPU time statistics, we
+/// can not implement process-CPU-time-based APIs like the simple clock() or
+/// clock_gettime() with CLOCK_REALTIME.
+
+#include "ssx.h"
+#include <errno.h>
+#include <time.h>
+
+/// Get time from a timer
+///
+/// \param clock_id This must be the constant CLOCK_REALTIME defined in
+/// <time.h>.
+///
+/// \param tp A pointer to a struct timespec populated by this API.
+///
+/// Although the Posix standard requires that clock_gettime() support
+/// CLOCK_REALTIME, CLOCK_REALTIME measures standard Unix time (seconds since
+/// the epoch) which is not available to SSX. SSX currently only supports
+/// CLOCK_MONOTONIC, which is derived from the SSX timebase.
+///
+/// \returns Either 0 for success, or -EINVAL in the event of an invalid
+/// argument (unrecognized \a clock_id, NULL \a tp pointer).
+
+int
+clock_gettime(clockid_t clock_id, struct timespec* tp)
+{
+ int rc;
+ SsxTimebase now;
+
+ if ((clock_id != CLOCK_MONOTONIC) || (tp == 0))
+ {
+ rc = -EINVAL;
+ }
+ else
+ {
+
+ now = ssx_timebase_get();
+ tp->tv_sec = now / SSX_TIMEBASE_FREQUENCY_HZ;
+ tp->tv_nsec =
+ ((now % SSX_TIMEBASE_FREQUENCY_HZ) * 1000000000) /
+ SSX_TIMEBASE_FREQUENCY_HZ;
+ rc = 0;
+ }
+
+ return rc;
+}
OpenPOWER on IntegriCloud