summaryrefslogtreecommitdiffstats
path: root/sbe/sample
diff options
context:
space:
mode:
authorDerk Rembold <rembold@de.ibm.com>2015-02-24 08:58:49 +0100
committerDerk Rembold <rembold@de.ibm.com>2015-02-24 09:19:34 -0600
commita4f967ae51ed4b9bad13145fa3085405f4b707a4 (patch)
tree15cf2e60705e46fba86ba30a6b3c5af43b629da1 /sbe/sample
parenta28f852be2197680c6864a8b66b8cb0743893471 (diff)
downloadtalos-sbe-a4f967ae51ed4b9bad13145fa3085405f4b707a4.tar.gz
talos-sbe-a4f967ae51ed4b9bad13145fa3085405f4b707a4.zip
checking sample see what happens
Change-Id: I583ffd4340ddc9ee73022b7fe72d3f947e7ce4c7 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/15960 Reviewed-by: Derk Rembold <rembold@de.ibm.com> Tested-by: Derk Rembold <rembold@de.ibm.com>
Diffstat (limited to 'sbe/sample')
-rw-r--r--sbe/sample/Makefile76
-rw-r--r--sbe/sample/img_defs.mk267
-rw-r--r--sbe/sample/link.cmd68
-rw-r--r--sbe/sample/pk_scom.c213
-rw-r--r--sbe/sample/pk_scom.h42
-rw-r--r--sbe/sample/pk_trace_wrap.c8
-rw-r--r--sbe/sample/pk_trace_wrap.h6
-rw-r--r--sbe/sample/sample_main.C100
-rw-r--r--sbe/sample/topfiles.mk5
9 files changed, 785 insertions, 0 deletions
diff --git a/sbe/sample/Makefile b/sbe/sample/Makefile
new file mode 100644
index 00000000..d19b1bc4
--- /dev/null
+++ b/sbe/sample/Makefile
@@ -0,0 +1,76 @@
+#remove this once we have a real compiler
+export P2P_ENABLE = 1
+
+#Pull in the definitions that affect all makefiles for this image
+include img_defs.mk
+
+#Pull in object file names for the top directory
+include topfiles.mk
+
+ifdef P2P_ENABLE
+include $(P2P_SRCDIR)/p2pfiles.mk
+endif
+
+PK_MAKE_DIR := $(PK_SRCDIR)/$(PPE_TYPE)
+OBJS := $(addprefix $(OBJDIR)/, $(TOP_OBJECTS))
+PKLIB := $(OBJDIR)/pk/libpk.a
+#COMMONLIB := $(OBJDIR)/commonlib/libcommon.a
+LIB_DIRS = -L$(OBJDIR)/pk #-L$(OBJDIR)/commonlib
+LINK_OBJS = $(OBJS) $(PKLIB) #$(COMMONLIB)
+LINK_SCRIPT = $(addprefix $(OBJDIR)/, linkscript)
+
+ifdef P2P_ENABLE
+P2PLIB := $(OBJDIR)/p2p/libp2p.a
+LIB_DIRS += -L$(OBJDIR)/p2p
+LINK_OBJS += $(P2PLIB)
+endif
+
+#default target is to make a binary application image
+#This removes all unecessary headers from the ELF executable
+$(OBJDIR)/$(IMAGE_NAME).bin $(OBJDIR)/$(IMAGE_NAME).dis: $(OBJDIR)/$(IMAGE_NAME).out
+ $(OBJCOPY) -O binary $< $(OBJDIR)/$(IMAGE_NAME).bin
+ $(OBJDUMP) -S $< > $(OBJDIR)/$(IMAGE_NAME).dis
+
+#create a linked ELF executable
+$(OBJDIR)/$(IMAGE_NAME).out: $(LINK_OBJS) $(LINK_SCRIPT)
+ $(LD) -e __system_reset -T$(LINK_SCRIPT) -Map $(OBJDIR)/$(IMAGE_NAME).map -Bstatic -o $(OBJDIR)/$(IMAGE_NAME).out $(LIB_DIRS) $(OBJS) -lpk -lp2p #-lcommon
+
+#pass the link command file through the C preprocessor to evaluate macros and remove comments
+$(LINK_SCRIPT): link.cmd
+ $(CPP) -E -x c++ -P $(DEFS) link.cmd -o $(LINK_SCRIPT)
+
+#Create an obj directory if needed
+$(LINK_OBJS) $(OBJS) $(OBJS:.o=.d): | $(OBJDIR)
+
+$(OBJDIR):
+ mkdir -p $(OBJDIR)
+
+.PHONY: clean $(PKLIB) $(P2PLIB)
+
+#Build macro-specific kernel code
+$(PKLIB):
+ $(MAKE) -I $(IMAGE_SRCDIR) -C $(PK_MAKE_DIR)
+
+#Build the code that is common for all processors (PPEs and 405)
+#$(COMMONLIB):
+# $(MAKE) -I $(IMAGE_SRCDIR) -C $(COMMONLIB_SRCDIR)
+
+ifdef P2P_ENABLE
+$(P2PLIB):
+ $(MAKE) -I $(IMAGE_SRCDIR) -C $(P2P_SRCDIR)
+endif
+
+# collect all of the trace hash files for this image into a single trexStringFile
+.PHONY : tracehash
+tracehash:
+ mkdir -p $(OBJDIR)
+ $(THASH) -c -d $(OBJDIR) -s $(OBJDIR)/trexStringFile
+
+#clean the kernel directory first, then the application level clean
+clean:
+ rm -fr $(OBJDIR)
+
+#Add dependencies to header files
+ifneq ($(MAKECMDGOALS),clean)
+include $(OBJS:.o=.d)
+endif
diff --git a/sbe/sample/img_defs.mk b/sbe/sample/img_defs.mk
new file mode 100644
index 00000000..eef28416
--- /dev/null
+++ b/sbe/sample/img_defs.mk
@@ -0,0 +1,267 @@
+# Make header for GPE PK builds
+#
+# The application may define the following variables to control the
+# build process:
+#
+# IMG_INCLUDES : Aplication-specific header search paths
+#
+# DEFS : A string of -D<symbol>[=<value>] to control compilation
+#
+# PK : Default ..; The path to the PK source code.
+# The default is set for building the PK
+# subdirectories.
+#
+# PK_THREAD_SUPPORT : (0/1, default 1); Compile PK thread and
+# semaphore suppprt
+#
+# PK_TIMER_SUPPORT : (0/1, default 1); Compile PK timer suppprt
+#
+# SIMICS_ENVIRONMENT : (0/1, current default 0); Compile for Simics
+#
+# SIMICS_MAGIC_PANIC : (0/1, current default 0); Use Simics Magic
+# breakpoint for PK_PANIC() instead of PowerPC trap.
+# Note that Simics does not model trap correctly in
+# external debug mode.
+#
+# GCC-O-LEVEL : The optimization level passed to GCC (default -Os). May
+# also be defined empty (GCC-O-LEVEL=) to disable
+# optimization. This variable can also be used to pass
+# any other non-default setting to GCC, e.g.
+# make GCC-O-LEVEL="-Os -fno-branch-count-reg"
+#
+# GCC-TOOL-PREFIX : The full path (including executable file prefixes) to
+# the GCC cross-development tools to use. The default is
+# "ppcnf-mcp5-"
+#
+# CTEPATH : This variable defaults to the afs/awd CTE tool
+# installation - The PORE binutils are stored there. If
+# you are not in Austin be sure to define CTEPATH in
+# your .profile.
+#
+# OBJDIR : target directory for all generated files
+
+IMAGE_NAME := sample_ppe
+
+PPE_TYPE := ppe
+
+ifndef IMAGE_SRCDIR
+export IMAGE_SRCDIR = $(abspath .)
+endif
+
+ifndef IMG_INCLUDES
+export IMG_INCLUDES = -I$(IMAGE_SRCDIR)
+endif
+
+ifndef BASE_OBJDIR
+export BASE_OBJDIR = $(abspath ../../../obj)
+endif
+
+export IMG_OBJDIR = $(BASE_OBJDIR)/$(IMAGE_NAME)
+
+ifndef PK_SRCDIR
+export PK_SRCDIR = $(abspath ../../pk)
+endif
+
+#ifndef COMMONLIB_SRCDIR
+#export COMMONLIB_SRCDIR = $(abspath ../lib/common)
+#endif
+
+ifndef GCC-TOOL-PREFIX
+#GCC-TOOL-PREFIX = $(CTEPATH)/tools/ppcgcc/prod/bin/powerpc-linux-
+GCC-TOOL-PREFIX = /afs/bb/u/rembold/openpower/op-build/output/host/usr/bin/powerpc64-linux-
+#GCC-TOOL-PREFIX = /afs/bb/u/rembold/openpower/op-build/buildroot/output/host/usr/bin/powerpc-linux-
+#GCC-TOOL-PREFIX = /afs/bb/u/rembold/openpower/op-build/output/host/usr/powerpc64-buildroot-linux-gnu/bin/
+#GCC-TOOL-PREFIX = /afs/bb/u/rembold/openpower/opcustom/op-build/buildroot/output/host/usr/bin/powerpc-linux-
+endif
+
+ifndef BINUTILS-TOOL-PREFIX
+BINUTILS-TOOL-PREFIX = $(CTEPATH)/tools/ppetools/prod/powerpc-eabi/bin/
+#BINUTILS-TOOL-PREFIX = /afs/bb/u/rembold/openpower/op-build/output/host/usr/bin/powerpc64-linux-
+endif
+
+ifndef P2P_SRCDIR
+export P2P_SRCDIR = $(abspath ../../tools/PowerPCtoPPE)
+endif
+
+ifndef PPETRACEPP_DIR
+export PPETRACEPP_DIR = $(abspath ../../tools/ppetracepp)
+endif
+
+OBJDIR = $(BASE_OBJDIR)$(SUB_OBJDIR)
+
+
+CC_ASM = $(GCC-TOOL-PREFIX)gcc
+TCC = $(PPETRACEPP_DIR)/ppetracepp $(GCC-TOOL-PREFIX)gcc
+CC = $(GCC-TOOL-PREFIX)gcc
+AS = $(BINUTILS-TOOL-PREFIX)as
+AR = $(BINUTILS-TOOL-PREFIX)ar
+LD = $(BINUTILS-TOOL-PREFIX)ld
+OBJDUMP = $(BINUTILS-TOOL-PREFIX)objdump
+OBJCOPY = $(BINUTILS-TOOL-PREFIX)objcopy
+TCPP = $(PPETRACEPP_DIR)/ppetracepp $(GCC-TOOL-PREFIX)gcc
+THASH = $(PPETRACEPP_DIR)/tracehash.pl
+CPP = $(GCC-TOOL-PREFIX)gcc
+
+ifdef P2P_ENABLE
+PCP = $(P2P_SRCDIR)/ppc-ppe-pcp.py
+endif
+
+
+ifndef CTEPATH
+$(warning The CTEPATH variable is not defined; Defaulting to /afs/awd)
+export CTEPATH = /afs/awd/projects/cte
+endif
+
+ifeq "$(PK_TIMER_SUPPORT)" ""
+PK_TIMER_SUPPORT = 1
+endif
+
+ifeq "$(PK_THREAD_SUPPORT)" ""
+PK_THREAD_SUPPORT = 1
+endif
+
+ifeq "$(PK_TRACE_SUPPORT)" ""
+PK_TRACE_SUPPORT = 1
+endif
+
+# Generate a 16bit trace string hash prefix value based on the name of this image. This will form
+# the upper 16 bits of the 32 bit trace hash values.
+ifndef PK_TRACE_HASH_PREFIX
+PK_TRACE_HASH_PREFIX := $(shell echo $(IMAGE_NAME) | md5sum | cut -c1-4 | xargs -i printf "%d" 0x{})
+endif
+
+
+ifndef GCC-O-LEVEL
+#GCC-O-LEVEL = -Os
+GCC-O-LEVEL = -O -g
+endif
+
+GCC-DEFS += -DIMAGE_NAME=$(IMAGE_NAME)
+GCC-DEFS += -DPK_TIMER_SUPPORT=$(PK_TIMER_SUPPORT)
+GCC-DEFS += -DPK_THREAD_SUPPORT=$(PK_THREAD_SUPPORT)
+GCC-DEFS += -DPK_TRACE_SUPPORT=$(PK_TRACE_SUPPORT)
+GCC-DEFS += -DPK_TRACE_HASH_PREFIX=$(PK_TRACE_HASH_PREFIX)
+GCC-DEFS += -D__PK__=1
+DEFS += $(GCC-DEFS)
+
+############################################################################
+
+INCLUDES += $(IMG_INCLUDES) \
+ -I$(PK_SRCDIR)/kernel -I$(PK_SRCDIR)/ppe42 -I$(PK_SRCDIR)/trace \
+ -I$(PK_SRCDIR)/$(PPE_TYPE) -I$(PK_SRCDIR)/../include \
+ -I$(PK_SRCDIR)/../tools/ppetracepp
+
+
+#INCLUDES += $(IMG_INCLUDES) \
+# -I$(PK_SRCDIR)/kernel -I$(PK_SRCDIR)/ppe42 -I$(PK_SRCDIR)/trace \
+# -I$(PK_SRCDIR)/$(PPE_TYPE) -I$(PK_SRCDIR)/../include \
+# -I$(PK_SRCDIR)/../tools/ppetracepp \
+# -I$(COMMONLIB_SRCDIR)
+
+PIPE-CFLAGS = -pipe -Wa,-m405
+
+GCC-CFLAGS += -Wall -fsigned-char -msoft-float \
+ -mcpu=405 -m32 -mmulhw -mmultiple \
+ -meabi -msdata=eabi \
+ -ffreestanding -fno-common -Werror \
+ -fno-inline-functions-called-once \
+ -ffixed-r11 -ffixed-r12 \
+ -ffixed-r14 -ffixed-r15 -ffixed-r16 -ffixed-r17 \
+ -ffixed-r18 -ffixed-r19 -ffixed-r20 -ffixed-r21 \
+ -ffixed-r22 -ffixed-r23 -ffixed-r24 -ffixed-r25 \
+ -ffixed-r26 -ffixed-r27 \
+ -ffixed-cr1 -ffixed-cr2 -ffixed-cr3 -ffixed-cr4 \
+ -ffixed-cr5 -ffixed-cr6 -ffixed-cr7 #-lstdc++
+
+
+#GCC-CFLAGS += -Wall -fsigned-char -msoft-float \
+# -mcpu=405 -mmulhw -mmultiple \
+# -meabi -msdata=eabi \
+# -ffreestanding -fno-common -Werror \
+# -fno-inline-functions-called-once \
+# -ffixed-r11 -ffixed-r12 \
+# -ffixed-r14 -ffixed-r15 -ffixed-r16 -ffixed-r17 \
+# -ffixed-r18 -ffixed-r19 -ffixed-r20 -ffixed-r21 \
+# -ffixed-r22 -ffixed-r23 -ffixed-r24 -ffixed-r25 \
+# -ffixed-r26 -ffixed-r27 \
+# -ffixed-cr1 -ffixed-cr2 -ffixed-cr3 -ffixed-cr4 \
+# -ffixed-cr5 -ffixed-cr6 -ffixed-cr7
+
+CFLAGS = -c $(GCC-CFLAGS) $(PIPE-CFLAGS) $(GCC-O-LEVEL) $(INCLUDES)
+
+CPPFLAGS = -E
+
+#ASFLAGS = -mppe42
+ASFLAGS = -mppe42
+
+ifdef P2P_ENABLE
+#use this to disable optimizations (fused compare/branch etc.)
+PCP-FLAG =
+
+#use this to enable optimizations
+#PCP-FLAG =
+endif
+############################################################################
+
+#override the GNU Make implicit rule for going from a .C to a .o
+%.o: %.C
+
+$(OBJDIR)/%.s: %.C
+ $(TCC) $(CFLAGS) $(DEFS) -S -o $@ $<
+
+
+#override the GNU Make implicit rule for going from a .c to a .o
+%.o: %.c
+
+$(OBJDIR)/%.s: %.c
+ $(TCC) $(CFLAGS) $(DEFS) -S -o $@ $<
+
+#override the GNU Make implicit rule for going from a .S to a .o
+%.o: %.S
+
+$(OBJDIR)/%.s: %.S
+ $(TCPP) $(CFLAGS) $(DEFS) $(CPPFLAGS) -o $@ $<
+.PRECIOUS: $(OBJDIR)/%.s
+
+ifndef P2P_ENABLE
+
+$(OBJDIR)/%.o: $(OBJDIR)/%.s
+ $(AS) $(ASFLAGS) -o $@ $<
+
+else
+
+$(OBJDIR)/%.es: $(OBJDIR)/%.s
+ $(PCP) $(PCP-FLAG) -f $<
+.PRECIOUS: $(OBJDIR)/%.es
+
+$(OBJDIR)/%.o: $(OBJDIR)/%.es
+ $(AS) $(ASFLAGS) -o $@ $<
+
+endif
+
+# From the GNU 'Make' manual - these scripts uses the preprocessor to
+# create dependency files (*.d), then mungs them slightly to make them
+# work as Make targets. The *.d files are include-ed in the
+# subdirectory Makefiles.
+
+$(OBJDIR)/%.d: %.C
+ @set -e; rm -f $@; \
+ echo -n "$(OBJDIR)/" > $@.$$$$; \
+ $(CC_ASM) -MM $(INCLUDES) $(CPPFLAGS) $(DEFS) $< >> $@.$$$$; \
+ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+ rm -f $@.$$$$
+
+$(OBJDIR)/%.d: %.c
+ @set -e; rm -f $@; \
+ echo -n "$(OBJDIR)/" > $@.$$$$; \
+ $(CC_ASM) -MM $(INCLUDES) $(CPPFLAGS) $(DEFS) $< >> $@.$$$$; \
+ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+ rm -f $@.$$$$
+
+$(OBJDIR)/%.d: %.S
+ @set -e; rm -f $@; \
+ echo -n "$(OBJDIR)/" > $@.$$$$; \
+ $(CC_ASM) -MM $(INCLUDES) $(CPPFLAGS) $(DEFS) $< >> $@.$$$$; \
+ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+ rm -f $@.$$$$
+
diff --git a/sbe/sample/link.cmd b/sbe/sample/link.cmd
new file mode 100644
index 00000000..3de03e18
--- /dev/null
+++ b/sbe/sample/link.cmd
@@ -0,0 +1,68 @@
+
+// Need to do this so that elf32-powerpc is not modified!
+#undef powerpc
+
+#ifndef INITIAL_STACK_SIZE
+#define INITIAL_STACK_SIZE 256
+#endif
+
+OUTPUT_FORMAT(elf32-powerpc);
+
+MEMORY
+{
+ sram : ORIGIN = 0xFFF40000, LENGTH = 0xc0000
+}
+
+SECTIONS
+{
+ . = 0xfff40000;
+ .text : {. = ALIGN(512); *(.vectors) *(.text)} > sram
+
+ ////////////////////////////////
+ // Read-only Data
+ ////////////////////////////////
+
+ . = ALIGN(8);
+ _RODATA_SECTION_BASE = .;
+
+ // SDA2 constant sections .sdata2 and .sbss2 must be adjacent to each
+ // other. Our SDATA sections are small so we'll use strictly positive
+ // offsets.
+
+ _SDA2_BASE_ = .;
+ .sdata2 . : { *(.sdata2) } > sram
+ .sbss2 . : { *(.sbss2) } > sram
+
+ // Other read-only data.
+
+ .rodata . : { *(.rodata*) *(.got2) } > sram
+
+ _RODATA_SECTION_SIZE = . - _RODATA_SECTION_BASE;
+
+ ////////////////////////////////
+ // Read-write Data
+ ////////////////////////////////
+
+ . = ALIGN(8);
+ _DATA_SECTION_BASE = .;
+
+ // SDA sections .sdata and .sbss must be adjacent to each
+ // other. Our SDATA sections are small so we'll use strictly positive
+ // offsets.
+
+ _SDA_BASE_ = .;
+ .sdata . : { *(.sdata) } > sram
+ .sbss . : { *(.sbss) } > sram
+
+ // Other read-write data
+ // It's not clear why boot.S is generating empty .glink,.iplt
+
+ .rela . : { *(.rela*) } > sram
+ .rwdata . : { *(.data) *(.bss) } > sram
+// .iplt . : { *(.iplt) } > sram
+
+ _PK_INITIAL_STACK_LIMIT = .;
+ . = . + INITIAL_STACK_SIZE;
+ _PK_INITIAL_STACK = . - 1;
+
+}
diff --git a/sbe/sample/pk_scom.c b/sbe/sample/pk_scom.c
new file mode 100644
index 00000000..9812cca3
--- /dev/null
+++ b/sbe/sample/pk_scom.c
@@ -0,0 +1,213 @@
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pk_scom.c
+/// \brief Lowest level SCOM definitions.
+///
+/// A fapi-level SCOM should call these functions.
+///
+/// Todo:
+/// - Poll PCB master for SCOM completion.
+/// - Return error code of SCOM fails.
+/// - Return error code if SCOM input parms violate rules.
+
+#include "pk.h"
+#include "pk_scom.h"
+
+
+uint32_t putscom( uint32_t i_chiplet_id, uint32_t i_address, uint64_t i_data)
+{
+ uint32_t l_cid=0;
+
+ // CMO-Declaring variables tied to specific registers enables us to protect
+ // the SCOM data and address variables used in the new stvd and lvd 64-bit
+ // data instructions. This protection is needed since the new instructions
+ // are not yet properly considered by the compiler.
+ // l_dataH is used to represent the "beginning" of the 64-bit data in d8
+ // (i.e., r8+r9).
+ uint32_t register l_dataH asm("r8")=0;
+ uint32_t register l_dataL asm("r9")=0;
+ uint32_t register l_addr_eff asm("r10")=0;
+ uint32_t register l_scratch asm("r31")=0;
+
+ if (i_chiplet_id)
+ {
+ // Accommodate two different ways of supplying the chiplet ID:
+ // 0xNN000000: Only bits in high-order two nibbles : Valid
+ // 0x000000NN: Only bits in low-order two nibbles : Valid
+ //
+ if ((i_chiplet_id & 0xFF000000) == i_chiplet_id)
+ {
+ // Valid: Chiplet ID in high-order two nibbles.
+ l_cid = i_chiplet_id;
+ }
+ else if ((i_chiplet_id & 0x000000FF) == i_chiplet_id)
+ {
+ // Valid: Chiplet ID in low-order two nibbles. Convert to high-order.
+ l_cid = i_chiplet_id << 24;
+ }
+ else
+ {
+ // Invalid: Invalid type of chiplet ID
+ PK_TRACE("putscom() : Invalid value of i_chiplet_id (=0x%08X)",i_chiplet_id);
+ return 1; //CMO-improve Return sensible rc here.
+ }
+
+ l_addr_eff = (i_address & 0x00FFFFFF) | l_cid;
+ }
+ else
+ {
+ // Chiplet ID is zero. Accept address as is.
+ // This is useful for PIB addresses and non-EX chiplets, and even for
+ // EX chiplets if the fully qualified EX chiplet addr is already known.
+ l_addr_eff = i_address;
+
+ }
+
+ l_dataH = (uint32_t)(i_data>>32);
+ l_dataL = (uint32_t)(i_data);
+
+ // CMO-The following sequence forces usage of l_dataH/L and l_addr_eff
+ // and thus the population of them as well.
+ // Further note that unless l_dataH/L are placed right before the following
+ // sequence, more specifically, if they're placed at the top of putscom(),
+ // r8, or l_dataH, might be overwritten in the if(chiplet_id) section.
+ // Secondly, we test l_addr_eff for non-zero through the CR0 register
+ // (which was populated in the "mr." instruction.) This is to convince the
+ // compiler that we actually used l_addr_eff for something.
+ // At present the test result causes no action except to execute the stvd
+ // instruction in either case.
+ asm volatile ( \
+ "mr. %0, %1 \n" \
+ : "=r"(l_scratch) \
+ : "r"(l_dataH) );
+ asm volatile ( \
+ "mr. %0, %1 \n" \
+ : "=r"(l_scratch) \
+ : "r"(l_dataL) );
+ asm volatile ( \
+ "mr. %0, %1 \n" \
+ : "=r"(l_scratch) \
+ : "r"(l_addr_eff) );
+ asm volatile ( \
+ "beq 0x4 \n" );
+
+
+/* asm volatile ( \
+ "stw %[data], 0(%[effective_address]) \n" \
+ : [data]"=r"(l_dataH) \
+ : [effective_address]"r"(l_addr_eff) );
+*/
+ // CMO-This instruction is not fully supported by the compiler (as of
+ // 20150108):
+ // - Correct: It is correctly translated into the proper OP code
+ // format.
+ // - Incorrect: The compiler does not seem to recognize the usage
+ // of the two l_xyz variables in that it doesn't
+ // know prior to this command that the registers that
+ // contain the values of l_xyz need to be protected
+ // up to this point. Thus, we are forced to use those
+ // two l_xyz variables in some dummy instructions just
+ // before this point in order to protect them.
+ asm volatile ( \
+ "stvd %[data], 0(%[effective_address]) \n" \
+ : [data]"=r"(l_dataH) \
+ : [effective_address]"r"(l_addr_eff) );
+
+ // CMO-TBD
+ // Check PIB response code in 0x00001007(17:19)
+ // Translate PIB rc to PK rc
+ // Does this rc get reset to zero on success?
+ // Do we need to check this rc prior to issuing the SCOM?
+
+ return 0;
+}
+
+
+uint32_t getscom( uint32_t i_chiplet_id, uint32_t i_address, uint64_t *o_data)
+{
+ uint32_t l_cid=0;
+
+ // CMO-Declaring variables tied to specific registers enables us to protect
+ // the SCOM data and address variables used in the new stvd and lvd 64-bit
+ // data instructions. This protection is needed since the new instructions
+ // are not yet properly considered by the compiler.
+ // l_dataH is used to represent the "beginning" of the 64-bit data in d8
+ // (i.e., r8+r9).
+ uint32_t register l_dataH asm("r8")=0;
+ uint32_t register l_dataL asm("r9")=0;
+ uint32_t register l_addr_eff asm("r10")=0;
+ uint32_t register l_scratch asm("r31")=0;
+
+ if (i_chiplet_id)
+ {
+ // Accommodate two different ways of supplying the chiplet ID:
+ // 0xNN000000: Only bits in high-order two nibbles : Valid
+ // 0x000000NN: Only bits in low-order two nibbles : Valid
+ //
+ if ((i_chiplet_id & 0xFF000000) == i_chiplet_id)
+ {
+ // Valid: Chiplet ID in high-order two nibbles.
+ l_cid = i_chiplet_id;
+ }
+ else if ((i_chiplet_id & 0x000000FF) == i_chiplet_id)
+ {
+ // Valid: Chiplet ID in low-order two nibbles. Convert to high-order.
+ l_cid = i_chiplet_id << 24;
+ }
+ else
+ {
+ // Invalid: Invalid type of chiplet ID
+ PK_TRACE("getscom() : Invalid value of i_chiplet_id (=0x%08X)",i_chiplet_id);
+ return 1; //CMO-improve Return sensible rc here.
+ }
+
+ l_addr_eff = (i_address & 0x00FFFFFF) | l_cid;
+ }
+ else
+ {
+ // Chiplet ID is zero. Accept address as is.
+ // This is useful for PIB addresses and non-EX chiplets, and even for
+ // EX chiplets if the fully qualified EX chiplet addr is already known.
+ l_addr_eff = i_address;
+ }
+
+ // CMO-The following sequence forces usage of l_addr_eff and thus the
+ // population of it as well.
+ // Secondly, we test l_addr_eff for non-zero through the CR0 register
+ // (which was populated in the "mr." instruction.) This is to convince the
+ // compiler that we actually used l_addr_eff for something.
+ // At present the test result causes no action except to execute the lvd
+ // instruction in either case.
+ asm volatile ( \
+ "mr. %0, %1 \n" \
+ : "=r"(l_scratch) \
+ : "r"(l_addr_eff) );
+ asm volatile ( \
+ "beq 0x4 \n" );
+
+ asm volatile ( \
+ "lvd %[data], 0(%[effective_address]) \n" \
+ : [data]"=r"(l_dataH) \
+ : [effective_address]"r"(l_addr_eff) );
+
+ // CMO-The following sequence moves the read data, in l_dataH/L, into the
+ // 64-bit o_data location.
+ asm volatile ( \
+ "stw %0, 0(%1) \n" \
+ : "=r"(l_dataH) \
+ : "r"(o_data) );
+ asm volatile ( \
+ "stw %0, 4(%1) \n" \
+ : "=r"(l_dataL) \
+ : "r"(o_data) );
+
+ // CMO-TBD
+ // Check PIB response code in 0x00001007(17:19)
+ // Translate PIB rc to PK rc
+
+ return 0;
+}
diff --git a/sbe/sample/pk_scom.h b/sbe/sample/pk_scom.h
new file mode 100644
index 00000000..72d5fa49
--- /dev/null
+++ b/sbe/sample/pk_scom.h
@@ -0,0 +1,42 @@
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file sample_main.c
+/// \brief Sample program that creates and starts a thread
+///
+/// This file demonstrates how to create a thread and run it. It also provides
+/// an example of how to add traces to the code.
+
+#ifndef __PK_SCOM_H__
+#define __PK_SCOM_H__
+
+/// SCOM operations return non-zero error codes that may or may not indicate
+/// an actual error, depending on which SCOM is begin accessed. This error
+/// code is returned as the value of get/putscom(). The error code value
+/// increases with teh severity of the error.
+#define CFAM_FSI_STATUS_0x00001007 0x00001007
+typedef union cfam_fsi_status_reg {
+ uint64_t value;
+ struct {
+ uint64_t ignore_fields1 : 17 ;
+ uint64_t pib_error_code : 3 ;
+ uint64_t igore_fields2 : 44 ;
+ } fields;
+} cfam_fsi_status_reg_t;
+#define PCB_ERROR_NONE 0
+#define PCB_ERROR_RESOURCE_OCCUPIED 1
+#define PCB_ERROR_CHIPLET_OFFLINE 2
+#define PCB_ERROR_PARTIAL_GOOD 3
+#define PCB_ERROR_ADDRESS_ERROR 4
+#define PCB_ERROR_CLOCK_ERROR 5
+#define PCB_ERROR_PACKET_ERROR 6
+#define PCB_ERROR_TIMEOUT 7
+
+uint32_t putscom( uint32_t i_chiplet, uint32_t i_address, uint64_t i_data);
+
+uint32_t getscom( uint32_t i_chiplet, uint32_t i_address, uint64_t *o_data);
+
+#endif // __PK_SCOM_H__
diff --git a/sbe/sample/pk_trace_wrap.c b/sbe/sample/pk_trace_wrap.c
new file mode 100644
index 00000000..0da319dc
--- /dev/null
+++ b/sbe/sample/pk_trace_wrap.c
@@ -0,0 +1,8 @@
+#include "pk_trace_wrap.h"
+#include "pk.h"
+#include "pk_trace.h"
+
+void pk_trace_wrap(const char* str)
+{
+ PK_TRACE("testsetest");
+}
diff --git a/sbe/sample/pk_trace_wrap.h b/sbe/sample/pk_trace_wrap.h
new file mode 100644
index 00000000..767cb54c
--- /dev/null
+++ b/sbe/sample/pk_trace_wrap.h
@@ -0,0 +1,6 @@
+#ifndef __PK_WRAP_WRAP_H__
+#define __PK_WRAP_WRAP__H__
+
+void pk_trace_wrap(const char*);
+
+#endif // __PK_WRAP_WRAP_H__
diff --git a/sbe/sample/sample_main.C b/sbe/sample/sample_main.C
new file mode 100644
index 00000000..7cc3822d
--- /dev/null
+++ b/sbe/sample/sample_main.C
@@ -0,0 +1,100 @@
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file sample_main.c
+/// \brief Sample program that creates and starts a thread
+///
+/// This file demonstrates how to create a thread and run it. It also provides
+/// an example of how to add traces to the code.
+extern "C" {
+#include "pk.h"
+#include "pk_trace.h"
+#include "pk_scom.h"
+#include "pk_trace_wrap.h"
+}
+#define KERNEL_STACK_SIZE 256
+#define MAIN_THREAD_STACK_SIZE 256
+
+//#include <stdint.h>
+//#include <istream>
+
+uint8_t G_kernel_stack[KERNEL_STACK_SIZE];
+uint8_t G_main_thread_stack[MAIN_THREAD_STACK_SIZE];
+PkThread G_main_thread;
+
+class Thetest {
+
+ public:
+ int i;
+
+};
+
+// A simple thread that just increments a local variable and sleeps
+void main_thread(void* arg)
+{
+ //Thetest mytest;
+
+ //mytest.i = 0;
+
+ //std::cout << "sdfds" << std::endl;
+
+ uint16_t a = 0;
+
+ pk_trace_wrap("sdfsdf");
+ //PK_TRACE("thread started");
+
+
+ while(1)
+ {
+ // PK_TRACE can take up to 4 parameters
+ // (not including the format string)
+ //PK_TRACE("thread seconds = %d", a);
+ pk_sleep(PK_SECONDS(1));
+
+ uint64_t i_data = 0x0110;
+
+ putscom(0x33333, 0x11111, i_data);
+
+ getscom(0x33333, 0x11111, &i_data);
+
+ a++;
+ }
+}
+
+
+// The main function is called by the boot code (after initializing some
+// registers)
+int main(int argc, char **argv)
+{
+ // initializes kernel data (stack, threads, timebase, timers, etc.)
+ pk_initialize((PkAddress)G_kernel_stack,
+ KERNEL_STACK_SIZE,
+ 0,
+ 500000000);
+
+ //PK_TRACE("Kernel init completed");
+
+ //Initialize the thread control block for G_main_thread
+ pk_thread_create(&G_main_thread,
+ (PkThreadRoutine)main_thread,
+ (void*)NULL,
+ (PkAddress)G_main_thread_stack,
+ (size_t)MAIN_THREAD_STACK_SIZE,
+ (PkThreadPriority)1);
+
+ //PK_TRACE_BIN("G_main_thread", &G_main_thread, sizeof(G_main_thread));
+
+ //Make G_main_thread runnable
+ pk_thread_resume(&G_main_thread);
+
+ //PK_TRACE("Starting thread(s)");
+
+ // Start running the highest priority thread.
+ // This function never returns
+ pk_start_threads();
+
+ return 0;
+}
diff --git a/sbe/sample/topfiles.mk b/sbe/sample/topfiles.mk
new file mode 100644
index 00000000..a10a2dca
--- /dev/null
+++ b/sbe/sample/topfiles.mk
@@ -0,0 +1,5 @@
+TOP-C-SOURCES = pk_trace_wrap.c pk_scom.c
+TOP-CPP-SOURCES = sample_main.C
+TOP-S-SOURCES =
+
+TOP_OBJECTS = $(TOP-C-SOURCES:.c=.o) $(TOP-CPP-SOURCES:.C=.o) $(TOP-S-SOURCES:.S=.o)
OpenPOWER on IntegriCloud