diff options
author | Derk Rembold <rembold@de.ibm.com> | 2015-02-24 08:58:49 +0100 |
---|---|---|
committer | Derk Rembold <rembold@de.ibm.com> | 2015-02-24 09:19:34 -0600 |
commit | a4f967ae51ed4b9bad13145fa3085405f4b707a4 (patch) | |
tree | 15cf2e60705e46fba86ba30a6b3c5af43b629da1 /sbe/sample | |
parent | a28f852be2197680c6864a8b66b8cb0743893471 (diff) | |
download | talos-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/Makefile | 76 | ||||
-rw-r--r-- | sbe/sample/img_defs.mk | 267 | ||||
-rw-r--r-- | sbe/sample/link.cmd | 68 | ||||
-rw-r--r-- | sbe/sample/pk_scom.c | 213 | ||||
-rw-r--r-- | sbe/sample/pk_scom.h | 42 | ||||
-rw-r--r-- | sbe/sample/pk_trace_wrap.c | 8 | ||||
-rw-r--r-- | sbe/sample/pk_trace_wrap.h | 6 | ||||
-rw-r--r-- | sbe/sample/sample_main.C | 100 | ||||
-rw-r--r-- | sbe/sample/topfiles.mk | 5 |
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) |