summaryrefslogtreecommitdiffstats
path: root/sbe
diff options
context:
space:
mode:
authorBasabjit Sengupta <basengup@in.ibm.com>2015-03-23 23:34:22 -0500
committerAmit J. Tendolkar <amit.tendolkar@in.ibm.com>2015-06-19 12:18:45 -0500
commit6a51c182508d13c8072e5ad8868ae63d41f28d99 (patch)
treea1fd4a5e404283aad8d042d99ed5ec80ca67cb73 /sbe
parent5e9cb6846e5860c4f82d234760c32ca561ac3854 (diff)
downloadtalos-sbe-6a51c182508d13c8072e5ad8868ae63d41f28d99.tar.gz
talos-sbe-6a51c182508d13c8072e5ad8868ae63d41f28d99.zip
SBE 0401 Add sbefw directory
Change-Id: I5aadd67bf2cd2c365032febadefbf8721c3ddcc4 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/16579 Reviewed-by: Amit J. Tendolkar <amit.tendolkar@in.ibm.com> Tested-by: Amit J. Tendolkar <amit.tendolkar@in.ibm.com>
Diffstat (limited to 'sbe')
-rw-r--r--sbe/sbefw/Makefile76
-rw-r--r--sbe/sbefw/img_defs.mk244
-rw-r--r--sbe/sbefw/link.cmd69
-rw-r--r--sbe/sbefw/pk_app_cfg.h104
-rw-r--r--sbe/sbefw/sbe_sp_intf.H198
-rw-r--r--sbe/sbefw/sbecmdiplcontrol.C30
-rw-r--r--sbe/sbefw/sbecmdiplcontrol.H26
-rw-r--r--sbe/sbefw/sbecmdparser.C162
-rw-r--r--sbe/sbefw/sbecmdparser.H92
-rw-r--r--sbe/sbefw/sbecmdprocessor.C239
-rw-r--r--sbe/sbefw/sbecmdreceiver.C160
-rw-r--r--sbe/sbefw/sbecmdscomaccess.C282
-rw-r--r--sbe/sbefw/sbecmdscomaccess.H35
-rw-r--r--sbe/sbefw/sbeexeintf.H171
-rw-r--r--sbe/sbefw/sbefifo.C250
-rw-r--r--sbe/sbefw/sbefifo.H356
-rw-r--r--sbe/sbefw/sbeirq.C104
-rw-r--r--sbe/sbefw/sbeirq.H84
-rw-r--r--sbe/sbefw/sbemain.C265
-rw-r--r--sbe/sbefw/sbetrace.H35
-rw-r--r--sbe/sbefw/topfiles.mk5
21 files changed, 2987 insertions, 0 deletions
diff --git a/sbe/sbefw/Makefile b/sbe/sbefw/Makefile
new file mode 100644
index 00000000..f986ce8b
--- /dev/null
+++ b/sbe/sbefw/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
+
+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/sbefw/img_defs.mk b/sbe/sbefw/img_defs.mk
new file mode 100644
index 00000000..4dbe10d7
--- /dev/null
+++ b/sbe/sbefw/img_defs.mk
@@ -0,0 +1,244 @@
+# 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 := sbe_main
+
+# BS - 20150312 - changes to support SBE interrupts
+PPE_TYPE := std
+
+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 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/
+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
+# BS - 20150312
+GCC-DEFS += -DUSE_PK_APP_CFG_H=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
+
+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++
+
+
+CFLAGS = -c $(GCC-CFLAGS) $(PIPE-CFLAGS) $(GCC-O-LEVEL) $(INCLUDES)
+
+CPPFLAGS = -E
+
+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/sbefw/link.cmd b/sbe/sbefw/link.cmd
new file mode 100644
index 00000000..a99cbbab
--- /dev/null
+++ b/sbe/sbefw/link.cmd
@@ -0,0 +1,69 @@
+
+// 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
+ sram : ORIGIN = 0xffff0000, LENGTH = 0x10000
+}
+
+SECTIONS
+{
+ . = 0xffff0000;
+ .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/sbefw/pk_app_cfg.h b/sbe/sbefw/pk_app_cfg.h
new file mode 100644
index 00000000..74e8ab79
--- /dev/null
+++ b/sbe/sbefw/pk_app_cfg.h
@@ -0,0 +1,104 @@
+/*
+ * @file: ppe/sbe/sbefw/pk_app_cfg.h
+ *
+ * @brief Application specific overrides go here.
+ *
+ */
+
+#ifndef __PK_APP_CFG_H__
+#define __PK_APP_CFG_H__
+
+#include "sbeirq.H"
+
+/*
+ * @brief Static configuration data for external interrupts:
+ * IRQ#, TYPE, POLARITY, ENABLE
+ *
+ */
+#define APPCFG_EXT_IRQS_CONFIG \
+ SBE_IRQ_START0 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ SBE_IRQ_START1 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ SBE_IRQ_INTR0 STD_IRQ_TYPE_LEVEL STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ SBE_IRQ_INTR1 STD_IRQ_TYPE_LEVEL STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ SBE_IRQ_DRTM_REQ STD_IRQ_TYPE_LEVEL STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ SBE_IRQ_SBEFIFO_RESET STD_IRQ_TYPE_LEVEL STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ SBE_IRQ_SBEFIFO_DATA STD_IRQ_TYPE_LEVEL STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+
+
+/*
+ * @brief This 64 bit mask specifies which of the interrupts are not to be used.
+ *
+ */
+#define APPCFG_IRQ_INVALID_MASK \
+(\
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_7) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_8) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_9) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_10) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_11) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_12) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_13) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_14) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_15) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_16) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_17) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_18) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_19) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_20) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_21) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_22) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_23) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_24) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_25) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_26) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_27) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_28) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_29) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_30) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_31) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_32) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_33) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_34) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_35) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_36) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_37) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_38) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_39) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_40) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_41) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_42) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_43) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_44) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_45) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_46) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_47) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_48) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_49) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_50) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_51) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_52) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_53) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_54) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_55) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_56) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_57) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_58) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_59) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_60) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_61) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_62) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_63))
+
+
+/*
+ * @brief Override the default behavior of the PK API error handling.
+ * Force PK to send the return code back to the application,
+ * instead of a kernel panic.
+ *
+ */
+#ifndef PK_ERROR_PANIC
+#define PK_ERROR_PANIC 0
+#endif
+
+
+#endif /*__PK_APP_CFG_H__*/
diff --git a/sbe/sbefw/sbe_sp_intf.H b/sbe/sbefw/sbe_sp_intf.H
new file mode 100644
index 00000000..f57ad7da
--- /dev/null
+++ b/sbe/sbefw/sbe_sp_intf.H
@@ -0,0 +1,198 @@
+/*
+ * @file sbe_sp_intf.H
+ *
+ * @brief This file contains the SP - SBE interface protocol common details
+ */
+
+#ifndef __SBEFW_SBE_SP_INTF_H
+#define __SBEFW_SBE_SP_INTF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * $Version: Conforms to SP-SBE Interface Spec v0.8
+ */
+
+/**
+ * @brief enums for SBE command classes
+ *
+*/
+enum sbeCommandClass
+{
+ SBE_CMD_CLASS_UNKNOWN = 0,
+ SBE_CMD_CLASS_IPL_CONTROL = 0xA1,
+ SBE_CMD_CLASS_SCOM_ACCESS = 0xA2,
+ SBE_CMD_CLASS_RING_ACCESS = 0xA3,
+ SBE_CMD_CLASS_MEMORY_ACCESS = 0xA4,
+ SBE_CMD_CLASS_REGISTER_ACCESS = 0xA5,
+ SBE_CMD_CLASS_ARRAY_ACCESS = 0xA6,
+ SBE_CMD_CLASS_INSTRUCTION_CONTROL = 0xA7,
+ SBE_CMD_CLASS_GENERIC_MESSAGE = 0xA8,
+ SBE_CMD_CLASS_MPIPL_COMMANDS = 0xA9,
+};
+
+/**
+ * @brief enums for SBE Istep Control command class
+ *
+*/
+enum sbeIplControlCommands
+{
+ SBE_CMD_EXECUTE_ISTEP = 0x01, /* Execute istep */
+ SBE_CMD_IS_SBE_IPL_DONE = 0x02, /* Check if SBE IPL Done */
+};
+
+/**
+ * @brief enums for SCOM Access Messages
+ *
+*/
+enum sbeScomAccessCommands
+{
+ SBE_CMD_GETSCOM = 0x01, /* Get SCOM */
+ SBE_CMD_PUTSCOM = 0x02, /* Put SCOM */
+ SBE_CMD_MODIFYSCOM = 0x03, /* Modify SCOM */
+ SBE_CMD_PUTSCOM_MASK = 0x04, /* Put SCOM under mask */
+ SBE_CMD_MULTISCOM = 0x05, /* Execute Multi SCOM */
+};
+
+/**
+ * @brief enums for Ring Access Messages
+ *
+*/
+enum sbeRingAccessCommands
+{
+ SBE_CMD_GETRING = 0x01, /* Get Ring */
+ SBE_CMD_PUTRING = 0x02, /* Put Ring */
+};
+
+/**
+ * @brief enums for Memory Access Messages
+ *
+*/
+enum sbeMemoryAccesCommands
+{
+ SBE_CMD_GETMEM = 0x01, /* Get Memory (Proc/PBA) */
+ SBE_CMD_PUTMEM = 0x02, /* Put Memory (Proc/PBA) */
+ SBE_CMD_GETSRAM = 0x03, /* Get Memory (SRAM) */
+ SBE_CMD_PUTSRAM = 0x04, /* Put Memory (SRAM) */
+};
+
+/**
+ * @brief enums for GPR/SPR/FPR Access Messages
+ *
+*/
+enum sbeRegisterAccessCommands
+{
+ SBE_CMD_GETREG = 0x01, /* Get Register (GPR,SPR,FPR) */
+ SBE_CMD_PUTREG = 0x02, /* Put Register (GPR,SPR,FPR) */
+};
+
+/**
+ * @brief enums for Trace Array Access Messages
+ *
+*/
+enum sbeArrayAccessCommands
+{
+ SBE_CMD_GET_FAST_ARRAY = 0x01, /* Get Fast Array */
+ SBE_CMD_GET_TRACE_ARRAY = 0x02, /* Get Trace Array */
+ SBE_CMD_CONTROL_TRACE_ARRAY = 0x03, /* Control Trace Array */
+};
+
+/**
+ * @brief enums for Instruction Control Messages
+ *
+*/
+enum sbeInstructionControlCommands
+{
+ SBE_CMD_CONTROL_INSTRUCTIONS = 0x01, /* Control Instructions */
+};
+
+/**
+ * @brief enums for Generic Messages
+ *
+*/
+enum sbeGenericMessageCommands
+{
+ SBE_CMD_GET_SBE_FFDC = 0x01, /* Get FFDC */
+ SBE_CMD_GET_SBE_VER = 0x02, /* GET SBE Version */
+ SBE_CMD_GET_SBE_CAPABILITIES = 0x03, /* GET SBE capabilities */
+ SBE_CMD_GET_FREQ_SUPPORTED = 0x04, /* Get Supported frequencies */
+ SBE_CMD_GET_SBE_STATE = 0x05, /* Get SBE State */
+};
+
+enum sbeMpIplCommands
+{
+ SBE_CMD_MPIPL_INVALID = 0x00,
+};
+
+/**
+ * @brief enums for primary SBE response
+ *
+*/
+enum sbePrimResponse
+{
+ SBE_PRI_OPERATION_SUCCESSFUL = 0x00,
+ SBE_PRI_INVALID_COMMAND = 0x01,
+ SBE_PRI_INVALID_DATA = 0x02,
+ SBE_PRI_SEQUENCE_ERROR = 0x03,
+ SBE_PRI_INTERNAL_ERROR = 0x04,
+ SBE_PRI_GENERIC_EXECUTION_FAILURE = 0xFE,
+};
+
+/**
+ * @brief enums for secondary SBE response
+ * @TODO via RTC: 129763
+ * Discuss on SBE_SEC_INVALID_TARGET_ID_PASSED
+ *
+*/
+enum sbeSecondaryResponse
+{
+ SBE_SEC_OPERATION_SUCCESSFUL = 0x00,
+ SBE_SEC_COMMAND_CLASS_NOT_SUPPORTED = 0x01,
+ SBE_SEC_COMMAND_NOT_SUPPORTED = 0x02,
+ SBE_SEC_INVALID_ADDRESS_PASSED = 0x03,
+ SBE_SEC_INVALID_TARGET_TYPE_PASSED = 0x04,
+ SBE_SEC_INVALID_TARGET_ID_PASSED = 0x05,
+ SBE_SEC_SPECIFIED_TARGET_NOT_PRESENT = 0x06,
+ SBE_SEC_SPECIFIED_TARGET_NOT_FUNCTIONAL = 0x07,
+ SBE_SEC_COMMAND_NOT_ALLOWED_IN_THIS_STATE = 0x08,
+ SBE_SEC_FUNCTIONALITY_NOT_SUPPORTED = 0x09,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION = 0x0A,
+ SBE_SEC_SECURITY_VALIDATION_FAILED = 0x0B,
+ SBE_SEC_OS_FAILURE = 0x0C,
+ SBE_SEC_FIFO_ACCESS_FAILURE = 0x0D,
+};
+
+/**
+ * @brief enums for SBE command timeout values
+ *
+*/
+enum sbeCmdRespTimeout
+{
+ SBE_CMD_TIMEOUT_SHORT_IN_MSEC = 100,
+ SBE_CMD_TIMEOUT_LONG_IN_MSEC = 30000,
+};
+
+/**
+ * @brief enums for PCB-PIB Generic Error codes
+ *
+*/
+enum sbePCBPIBErrorRC
+{
+ SBE_PCB_PIB_ERROR_NONE = 0x00,
+ SBE_PCB_PIB_ERROR_RESOURCE_OCCUPIED = 0x01,
+ SBE_PCB_PIB_ERROR_CHIPLET_OFFLINE = 0x02,
+ SBE_PCB_PIB_ERROR_PARTIAL_GOOD = 0x03,
+ SBE_PCB_PIB_ERROR_ADDRESS_ERROR = 0x04,
+ SBE_PCB_PIB_ERROR_CLOCK_ERROR = 0x05,
+ SBE_PCB_PIB_ERROR_PACKET_ERROR = 0x06,
+ SBE_PCB_PIB_ERROR_TIMEOUT = 0x07,
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SBEFW_SBE_SP_INTF_H */
diff --git a/sbe/sbefw/sbecmdiplcontrol.C b/sbe/sbefw/sbecmdiplcontrol.C
new file mode 100644
index 00000000..70f45805
--- /dev/null
+++ b/sbe/sbefw/sbecmdiplcontrol.C
@@ -0,0 +1,30 @@
+/*
+ * @file: ppe/sbe/sbefw/sbecmdiplcontrol.C
+ *
+ * @brief This file contains the SBE FIFO Commands
+ *
+ */
+
+#include "sbecmdiplcontrol.H"
+#include "sbefifo.H"
+#include "sbetrace.H"
+
+
+uint32_t sbeExecuteIstep (uint8_t *i_pArg)
+{
+ uint32_t l_rc = 0;
+ SBE_TRACE("sbeExecuteIstep");
+
+
+ return l_rc;
+}
+
+
+uint32_t sbeWaitForSbeIplDone (uint8_t *i_pArg)
+{
+ uint32_t l_rc = 0;
+ SBE_TRACE("sbeWaitForSbeIplDone");
+
+
+ return l_rc;
+}
diff --git a/sbe/sbefw/sbecmdiplcontrol.H b/sbe/sbefw/sbecmdiplcontrol.H
new file mode 100644
index 00000000..286dea82
--- /dev/null
+++ b/sbe/sbefw/sbecmdiplcontrol.H
@@ -0,0 +1,26 @@
+/*
+ * @file: ppe/sbe/sbefw/sbecmdiplcontrol.H
+ *
+ * @brief This file contains the SBE command details
+ *
+ * Change Log *****************************************************************
+ * Flag Defect/Feature User Date Description
+ * ---- -------------- ---- ---- -----------
+ * basengup 2015/03/17 Created
+ *
+ * @endverbatim
+ */
+
+#ifndef __SBEFW_SBECMDIPLCONTROL_H
+#define __SBEFW_SBECMDIPLCONTROL_H
+
+#include <stdint.h>
+
+
+uint32_t sbeExecuteIstep (uint8_t *i_pArg);
+
+
+uint32_t sbeWaitForSbeIplDone (uint8_t *i_pArg);
+
+
+#endif // __SBEFW_SBECMDIPLCONTROL_H
diff --git a/sbe/sbefw/sbecmdparser.C b/sbe/sbefw/sbecmdparser.C
new file mode 100644
index 00000000..24b968eb
--- /dev/null
+++ b/sbe/sbefw/sbecmdparser.C
@@ -0,0 +1,162 @@
+/*
+ * @file: ppe/sbe/sbefw/sbecmdparser.C
+ *
+ * @brief This file contains the SBE FIFO Commands
+ *
+ */
+
+#include "sbecmdparser.H"
+#include "sbecmdscomaccess.H"
+#include "sbecmdiplcontrol.H"
+#include "sbetrace.H"
+#include "sbe_sp_intf.H"
+
+
+////////////////////////////////////////////////////////////////
+// @brief g_sbeScomCmdArray
+////////////////////////////////////////////////////////////////
+static sbeCmdStruct_t g_sbeScomCmdArray [] =
+{
+ {sbeGetScom,
+ SBE_CMD_GETSCOM,
+ SBE_FENCE_AT_CONTINUOUS_IPL,
+ },
+
+ {sbePutScom,
+ SBE_CMD_PUTSCOM,
+ SBE_FENCE_AT_CONTINUOUS_IPL,
+ },
+};
+
+////////////////////////////////////////////////////////////////
+// @brief g_sbeScomCmdArray
+//
+////////////////////////////////////////////////////////////////
+static sbeCmdStruct_t g_sbeIplControlCmdArray [] =
+{
+ {sbeExecuteIstep,
+ SBE_CMD_EXECUTE_ISTEP,
+ SBE_FENCE_AT_CONTINUOUS_IPL|SBE_FENCE_AT_RUNTIME|SBE_FENCE_AT_MPIPL,
+ },
+
+ {sbeWaitForSbeIplDone,
+ SBE_CMD_IS_SBE_IPL_DONE,
+ SBE_FENCE_AT_ISTEP|SBE_FENCE_AT_RUNTIME|SBE_FENCE_AT_MPIPL,
+ },
+};
+
+
+
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+uint8_t sbeGetCmdStructAttr (const uint8_t i_cmdClass,
+ sbeCmdStruct_t **o_ppCmd)
+{
+ #define SBE_FUNC " sbeGetCmdStructAttr "
+ SBE_DEBUG(SBE_FUNC);
+ uint8_t l_numCmds = 0;
+ *o_ppCmd = NULL;
+
+ switch(i_cmdClass)
+ {
+ case SBE_CMD_CLASS_IPL_CONTROL:
+ // @TODO via RTC : 128655
+ // Use C++ style typecase
+ l_numCmds = sizeof(g_sbeIplControlCmdArray) /
+ sizeof(sbeCmdStruct_t);
+ *o_ppCmd = (sbeCmdStruct_t*)g_sbeIplControlCmdArray;
+ break;
+ case SBE_CMD_CLASS_SCOM_ACCESS:
+ l_numCmds = sizeof(g_sbeScomCmdArray) /
+ sizeof(sbeCmdStruct_t);
+ *o_ppCmd = (sbeCmdStruct_t*)g_sbeScomCmdArray;
+ break;
+
+ // This will grow with each class of chipOp in future
+ default:
+ break;
+ }
+ return l_numCmds;
+ #undef SBE_FUNC
+}
+
+
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+uint8_t sbeValidateCmdClass (const uint8_t i_cmdClass,
+ const uint8_t i_cmdOpcode)
+{
+ #define SBE_FUNC " sbeValidateCmdClass "
+ uint8_t l_rc = SBE_SEC_COMMAND_NOT_SUPPORTED;
+
+ SBE_DEBUG(SBE_FUNC"i_cmdClass[0x%02X], "
+ "i_cmdOpcode[0x%02X]", i_cmdClass, i_cmdOpcode);
+
+ do
+ {
+ uint8_t l_numCmds = 0;
+ sbeCmdStruct_t *l_pCmd = NULL;
+
+ l_numCmds = sbeGetCmdStructAttr (i_cmdClass, &l_pCmd);
+ if (!l_numCmds)
+ {
+ // Command class not supported
+ l_rc = SBE_SEC_COMMAND_CLASS_NOT_SUPPORTED;
+ break;
+ }
+
+ // @TODO via RTC : 128654
+ // Analyze on merging the validation functions into one
+ // and also on using loop vs switch case performance
+ for (uint8_t l_cnt = 0; l_cnt < l_numCmds; ++l_cnt, ++l_pCmd)
+ {
+ if (i_cmdOpcode == l_pCmd->cmd_opcode)
+ {
+ // Command found
+ l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ break;
+ }
+ }
+ } while (false);
+
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+bool sbeIsCmdAllowedAtState (const uint8_t i_cmdClass,
+ const uint8_t i_cmdOpcode)
+{
+ // @TODO via RTC : 126146
+ // SBE state management
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+sbeCmdFunc_t sbeFindCmdFunc (const uint8_t i_cmdClass,
+ const uint8_t i_cmdOpcode)
+
+{
+ #define SBE_FUNC " sbeFindCmdFunc "
+ uint8_t l_numCmds = 0;
+ sbeCmdStruct_t *l_pCmd = NULL;
+
+ l_numCmds = sbeGetCmdStructAttr (i_cmdClass, &l_pCmd);
+
+ SBE_DEBUG(SBE_FUNC"i_cmdClass[0x%02X], "
+ "i_cmdOpcode[0x%02X], l_numCmds[0x%02X]",
+ i_cmdClass, i_cmdOpcode, l_numCmds);
+
+ for (uint8_t l_cnt = 0; l_cnt < l_numCmds; ++l_cnt, ++l_pCmd)
+ {
+ if (i_cmdOpcode == l_pCmd->cmd_opcode)
+ {
+ break;
+ }
+ }
+
+ return l_pCmd ? (l_pCmd->cmd_func) : NULL;
+ #undef SBE_FUNC
+}
diff --git a/sbe/sbefw/sbecmdparser.H b/sbe/sbefw/sbecmdparser.H
new file mode 100644
index 00000000..68c6ec42
--- /dev/null
+++ b/sbe/sbefw/sbecmdparser.H
@@ -0,0 +1,92 @@
+/*
+ * @file: ppe/sbe/sbefw/sbecmdparser.H
+ *
+ * @brief This file contains the SBE command details
+ *
+ */
+
+#ifndef __SBEFW_SBECMDPARSER_H
+#define __SBEFW_SBECMDPARSER_H
+
+#include <stdint.h>
+
+
+/**
+ * @brief SBE Command structure associating an opcode of a command
+ * to the processing function as well as the allowed states
+ *
+ */
+typedef uint32_t (*sbeChipOpFunc_t) (uint8_t *i_pArg);
+
+typedef struct {
+ sbeChipOpFunc_t cmd_func; /* Command function pointer */
+ uint8_t cmd_opcode; /* Command opcode */
+ uint8_t cmd_state_fence; /* Command fencing based on SBE state */
+} sbeCmdStruct_t;
+
+
+/**
+ * @brief SBE Command Fence attributes
+ *
+ */
+enum sbe_command_fence_attrs
+{
+ SBE_FENCE_AT_ISTEP = 0x80, ///< Fence off the cmd at istep state
+ SBE_FENCE_AT_CONTINUOUS_IPL = 0x40, ///< Fence off the cmd at cont IPL
+ SBE_FENCE_AT_RUNTIME = 0x20, ///< Fence off the cmd at Runtime state
+ SBE_FENCE_AT_MPIPL = 0x10, ///< Fence off the cmd at MPIPL state
+};
+
+
+/**
+ * @brief sbeValidateCmdClass Validates the command class and opcode
+ *
+ * @param[in] i_cmdClass Command class code
+ * @param[in] i_cmdOpcode Command opcode
+ *
+ * @return uint8_t return code
+ * SBE_SEC_OPERATION_SUCCESSFUL - Command found
+ * SBE_SEC_COMMAND_CLASS_NOT_SUPPORTED
+ * SBE_SEC_COMMAND_NOT_SUPPORTED
+ */
+uint8_t sbeValidateCmdClass (const uint8_t i_cmdClass,
+ const uint8_t i_cmdOpcode);
+
+/**
+ * @brief sbeIsCmdAllowedAtState Validates if the command is allowed
+ * at the current SBE state
+ *
+ * @param[in] i_cmdClass Command class code
+ * @param[in] i_cmdOpcode Command opcode
+ *
+ * @return true command is allowed at the current state
+ * false command is not allowed at the current state
+ */
+bool sbeIsCmdAllowedAtState (const uint8_t i_cmdClass,
+ const uint8_t i_cmdOpcode);
+
+
+/**
+ * @brief sbeCmdFunc_t Typical signature for any SBE ChipOp back-end function
+ *
+ * @param[in] uint8_t *i_pArg Pointer to the argument to be passed to
+ * the chipOp function
+ *
+ * @return uint32_t Return code from the chipOp function
+ */
+typedef uint32_t ( *sbeCmdFunc_t ) (uint8_t *i_pArg);
+
+
+/**
+ * @brief sbeFindCmdFunc Finds the function corresponding to the command
+ *
+ * @param[in] i_cmdClass Command class code
+ * @param[in] i_cmdOpcode Command opcode
+ *
+ * @return sbeCmdFunc_t A pointer to the corresponding ChipOps function
+ */
+sbeCmdFunc_t sbeFindCmdFunc (const uint8_t i_cmdClass,
+ const uint8_t i_cmdOpcode);
+
+
+#endif // __SBEFW_SBECMDPARSER_H
diff --git a/sbe/sbefw/sbecmdprocessor.C b/sbe/sbefw/sbecmdprocessor.C
new file mode 100644
index 00000000..b5d95bd3
--- /dev/null
+++ b/sbe/sbefw/sbecmdprocessor.C
@@ -0,0 +1,239 @@
+/*
+ * @file: ppe/sbe/sbefw/sbecmdprocessor.C
+ *
+ * @brief This file contains the SBE Command processing Thread Routines
+ *
+ */
+
+
+#include "sbeexeintf.H"
+#include "sbefifo.H"
+#include "sbecmdparser.H"
+#include "sbeirq.H"
+#include "sbetrace.H"
+#include "sbe_sp_intf.H"
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+void sbeSyncCommandProcessor_routine(void *i_pArg)
+{
+ #define SBE_FUNC " sbeSyncCommandProcessor_routine "
+ SBE_ENTER(SBE_FUNC);
+
+ do
+ {
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint8_t l_dist2StatusHdr = 0;
+ uint32_t l_sbeDownFifoRespBuf[4] = {0};
+
+ // Wait for new command processing
+ int l_rcPk = pk_semaphore_pend (
+ &g_sbeSemCmdProcess, PK_WAIT_FOREVER);
+
+ do
+ {
+ uint16_t l_primStatus = g_sbeCmdRespHdr.prim_status;
+ uint16_t l_secStatus = g_sbeCmdRespHdr.sec_status ;
+ SBE_DEBUG (SBE_FUNC"l_primStatus=[0x%04X], l_secStatus=[0x%04X]",
+ l_primStatus, l_secStatus);
+
+ // PK API failure
+ if (l_rcPk != PK_OK)
+ {
+ SBE_ERROR(SBE_FUNC"pk_semaphore_pend failed, "
+ "l_rcPk=%d, g_sbeSemCmdRecv.count=%d",
+ l_rcPk, g_sbeSemCmdRecv.count);
+
+ // if the command receiver thread already updated
+ // the response status codes, don't override them.
+ if (l_primStatus != SBE_PRI_OPERATION_SUCCESSFUL)
+ {
+ l_primStatus = SBE_PRI_INTERNAL_ERROR;
+ l_secStatus = SBE_SEC_OS_FAILURE;
+ }
+ }
+
+ SBE_DEBUG(SBE_FUNC"unblocked");
+
+ // if there was a PK API failure or the
+ // command receiver thread indicated of
+ // a failure due to
+ // Command Validation or
+ // FIFO Reset request
+ if (l_primStatus)
+ {
+ uint8_t l_len2dequeue = 0;
+ switch (l_primStatus)
+ {
+ case SBE_FIFO_RESET_RECEIVED:
+ SBE_ERROR(SBE_FUNC"FIFO reset received");
+ l_rc = SBE_FIFO_RC_RESET;
+ break;
+
+ case SBE_PRI_INVALID_COMMAND:
+ // Command or SBE state validation failed
+ // just follow through
+
+ case SBE_PRI_INTERNAL_ERROR:
+ // Flush out the upstream FIFO till EOT arrives
+ l_len2dequeue = 1;
+ l_rc = sbeUpFifoDeq_mult (l_len2dequeue, NULL, true);
+ if (l_rc == SBE_FIFO_RC_RESET)
+ {
+ break;
+ }
+
+ // Not handling any other RC from sbeUpFifoDeq_mult
+ // while flushing out to keep this code simple.
+
+ // Don't break here to force the flow through
+ // the next case to enqueue the response into
+ // the downstream FIFO
+
+ case SBE_PRI_INVALID_DATA:
+ // SBE caller already wrongly sent EOT
+ // before sending two mandatory header entries
+ //
+ // enqueue the response payload now into
+ // the downstream FIFO
+
+ // @TODO via RTC : 130575
+ // Optimize RC handling infrastructure code
+
+ // Build the response packet first
+ sbeBuildMinRespHdr(&l_sbeDownFifoRespBuf[0],
+ l_dist2StatusHdr,
+ l_primStatus,
+ l_secStatus,
+ 0);
+
+ // Now enqueue into the downstream FIFO
+ l_rc = sbeDownFifoEnq_mult (++l_dist2StatusHdr,
+ &l_sbeDownFifoRespBuf[0]);
+ if (l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"sbeDownFifoEnq_mult failure,"
+ " l_rc[0x%X]", l_rc);
+ }
+ break;
+
+ // Signal EOT in Downstream FIFO
+ l_rc = sbeDownFifoSignalEot();
+ if (l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"sbeDownFifoSignalEot failure,"
+ " l_rc[0x0%08X]", l_rc);
+ break;
+ }
+
+ default:
+ break;
+ } // End switch
+
+ break;
+ }
+
+ SBE_DEBUG(SBE_FUNC"New cmd arrived, g_sbeSemCmdProcess.count=%d",
+ g_sbeSemCmdProcess.count);
+
+ uint8_t l_cmdClass = 0;
+ uint8_t l_cmdOpCode = 0;
+ uint32_t (*l_pFuncP) (uint8_t *) ;
+
+ // @TODO via RTC: 128658
+ // Review if Mutex protection is required
+ // for all the globals used between threads
+ l_cmdClass = (uint8_t)(g_sbeCmdHdr.cmdReqHdr_cmdClass>>8) ;
+ l_cmdOpCode = (uint8_t)(g_sbeCmdHdr.cmdReqHdr_cmdClass) ;
+
+ // Get the command function
+ l_pFuncP = sbeFindCmdFunc (l_cmdClass, l_cmdOpCode) ;
+
+ if (!l_pFuncP)
+ {
+ // No Supported function found
+ SBE_ERROR(SBE_FUNC"No supported function");
+ l_rc = SBE_FUNC_NOT_SUPPORTED;
+
+ // @TODO via RTC : 129166
+ // force assert
+ break;
+ }
+
+ // Call the ChipOp function
+ l_rc = l_pFuncP ((uint8_t *)i_pArg);
+
+ } while(false); // Inner do..while loop ends here
+
+ SBE_DEBUG(SBE_FUNC"l_rc=[0x%08X]", l_rc);
+
+ // Handle FIFO reset case
+ if (l_rc == SBE_FIFO_RC_RESET)
+ {
+ // @TODO via RTC : 126147
+ // Handle FIFO reset flow
+ pk_irq_enable(SBE_IRQ_SBEFIFO_DATA);
+ continue;
+ }
+
+ switch (l_rc)
+ {
+ // EOT arrived prematurely in upstream FIFO
+ // or there were unexpected data in upstream
+ // FIFO
+ case SBE_FIFO_RC_EOT_ACKED:
+ case SBE_FIFO_RC_EOT_ACK_FAILED:
+ SBE_ERROR(SBE_FUNC"Received unexpected EOT, l_rc[0x%08X]",
+ l_rc);
+ sbeBuildMinRespHdr(&l_sbeDownFifoRespBuf[0],
+ l_dist2StatusHdr,
+ SBE_PRI_INVALID_DATA,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION,
+ 0);
+ l_rc = sbeDownFifoEnq_mult (++l_dist2StatusHdr,
+ &l_sbeDownFifoRespBuf[0]);
+ if (l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"sbeDownFifoEnq_mult failure,"
+ " l_rc[0x0%08X]", l_rc);
+ // not attempting to signal EOT
+ break;
+ }
+ // Follow through to signal EOT in downstream
+
+ case SBE_SEC_OPERATION_SUCCESSFUL: // Successful execution
+ // Signal EOT in Downstream FIFO
+ l_rc = sbeDownFifoSignalEot();
+ if (l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"sbeDownFifoSignalEot failure,"
+ " l_rc[0x0%08X]", l_rc);
+ }
+ SBE_INFO(SBE_FUNC"ChipOp Done");
+ break;
+
+ default:
+ break;
+ }
+
+ // @TODO via RTC : 126147
+ // Review all the scenarios
+ // Enable the new data available interrupt
+ pk_irq_enable(SBE_IRQ_SBEFIFO_DATA);
+
+ } while(true); // Thread always exists
+}
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+void sbeAsyncCommandProcessor_routine(void *arg)
+{
+ SBE_TRACE("sbeAsyncCommandProcessor Thread started");
+
+ do
+ {
+ // @TODO RTC via : 130392
+ // Add infrastructure for host interface
+
+ } while(0);
+}
diff --git a/sbe/sbefw/sbecmdreceiver.C b/sbe/sbefw/sbecmdreceiver.C
new file mode 100644
index 00000000..e15ecd1c
--- /dev/null
+++ b/sbe/sbefw/sbecmdreceiver.C
@@ -0,0 +1,160 @@
+/*
+ * @file: ppe/sbe/sbefw/sbecmdreceiver.C
+ *
+ * @brief This file contains the SBE Command Receiver Thread Routine
+ *
+ */
+
+
+#include "sbeexeintf.H"
+#include "sbefifo.H"
+#include "sbecmdparser.H"
+#include "sbeirq.H"
+#include "sbetrace.H"
+#include "sbe_sp_intf.H"
+
+sbeCmdHdr_t g_sbeCmdHdr ;
+sbeCmdRespHdr_t g_sbeCmdRespHdr;
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+void sbeCommandReceiver_routine(void *i_pArg)
+{
+ #define SBE_FUNC " sbeCommandReceiver_routine "
+ SBE_ENTER(SBE_FUNC);
+
+ do
+ {
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+
+ // @TODO via RTC: 128944
+ // Read Scratchpad
+
+ // Wait for new data in FIFO or FIFO reset interrupt
+ int l_rcPk = pk_semaphore_pend (&g_sbeSemCmdRecv, PK_WAIT_FOREVER);
+
+ // @TODO via RTC: 128658
+ // Review if Mutex protection is required
+ // for all the globals used between threads
+ g_sbeCmdRespHdr.prim_status = SBE_PRI_OPERATION_SUCCESSFUL;
+ g_sbeCmdRespHdr.sec_status = SBE_SEC_OPERATION_SUCCESSFUL;
+ g_sbeCmdHdr.cmdReqHdr_cmdClass = SBE_CMD_CLASS_UNKNOWN;
+
+ // inner loop for command handling
+ do
+ {
+ // pk API failure
+ if (l_rcPk != PK_OK)
+ {
+ break;
+ }
+
+ SBE_DEBUG(SBE_FUNC"unblocked");
+
+ // @TODO via RTC: 128943
+ // Host services / OPAL handling
+
+ // @TODO via RTC: 128945
+ // Handle protocol violation if needed (a long term goal)
+
+ // The responsibility of this thread is limited to dequeueing
+ // only the first two word entries from the protocol header.
+ uint32_t l_ufifo_data[2] = {0};
+ uint8_t l_len2dequeue = 2;
+ l_rc = sbeUpFifoDeq_mult ( l_len2dequeue, &l_ufifo_data[0] );
+
+ // If FIFO reset is requested,
+ if (l_rc == SBE_FIFO_RC_RESET)
+ {
+ SBE_ERROR(SBE_FUNC"FIFO reset received");
+ g_sbeCmdRespHdr.prim_status =
+ (uint16_t)SBE_FIFO_RESET_RECEIVED;
+ g_sbeCmdRespHdr.sec_status =
+ (uint16_t)SBE_SEC_GENERIC_FAILURE_IN_EXECUTION;
+ break;
+ }
+
+ // If we received EOT pre-maturely or
+ // got an error while Ack'ing EOT
+ if ( (l_rc == SBE_FIFO_RC_EOT_ACKED) ||
+ (l_rc == SBE_FIFO_RC_EOT_ACK_FAILED) )
+ {
+ SBE_ERROR(SBE_FUNC"sbeUpFifoDeq_mult failure, "
+ " l_rc=[0x%08X]", l_rc);
+ g_sbeCmdRespHdr.prim_status =
+ SBE_PRI_INVALID_DATA;
+ g_sbeCmdRespHdr.sec_status =
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION;
+ l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ break;
+ }
+
+ // Any other FIFO access issue
+ if ( l_rc != SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ SBE_ERROR(SBE_FUNC"sbeUpFifoDeq_mult failue, "
+ "l_rc=[0x%08X]", l_rc);
+ break;
+ }
+
+ // Successfully dequeued two mandatory entries;
+ // First entry corresponds to command length parameter
+ g_sbeCmdHdr.cmdReqHdr_cmdLen = l_ufifo_data[0];
+
+ // Second entry contains the command class
+ // and the opcode parameters
+ g_sbeCmdHdr.cmdReqHdr_cmdClass = l_ufifo_data[1];
+
+ // validate the command class and sub-class opcodes
+ l_rc = sbeValidateCmdClass (
+ (uint8_t)(g_sbeCmdHdr.cmdReqHdr_cmdClass>>8),
+ (uint8_t)(g_sbeCmdHdr.cmdReqHdr_cmdClass) ) ;
+
+ if (l_rc)
+ {
+ // Command Validation failed;
+ SBE_ERROR(SBE_FUNC"Command validation failed");
+ g_sbeCmdRespHdr.prim_status = SBE_PRI_INVALID_COMMAND;
+ g_sbeCmdRespHdr.sec_status = l_rc;
+ l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ break;
+ }
+
+ // @TODO via RTC: 126146
+ // validate state machine constraints
+
+ } while (false); // Inner do..while ends
+
+ // Unblock the command processor thread
+ // if we could dequeue the header successfully
+ if ((l_rcPk == PK_OK) && (l_rc == SBE_SEC_OPERATION_SUCCESSFUL))
+ {
+ l_rcPk = pk_semaphore_post(&g_sbeSemCmdProcess);
+ }
+
+ if ((l_rcPk != PK_OK) || (l_rc != SBE_SEC_OPERATION_SUCCESSFUL))
+ {
+ // It's likely a code bug or PK failure, or
+ // FIFO reset request arrived or any other
+ // FIFO access failure.
+
+ // @TODO via RTC : 129166
+ // Review if we need to add ASSERT here
+
+ // Add Error trace, collect FFDC and
+ // continue wait for the next interrupt
+ SBE_ERROR(SBE_FUNC"Unexpected failure, "
+ "l_rcPk=[%d], g_sbeSemCmdProcess.count=[%d], l_rc=[%d]",
+ l_rcPk, g_sbeSemCmdProcess.count, l_rc);
+
+ pk_irq_enable(SBE_IRQ_SBEFIFO_DATA);
+
+ continue;
+ }
+
+ SBE_DEBUG(SBE_FUNC"Posted g_sbeSemCmdProcess, "
+ "g_sbeSemCmdProcess.count=[%d]", g_sbeSemCmdProcess.count);
+
+ } while (true); // thread always exists
+ #undef SBE_FUNC
+}
diff --git a/sbe/sbefw/sbecmdscomaccess.C b/sbe/sbefw/sbecmdscomaccess.C
new file mode 100644
index 00000000..5b946ffa
--- /dev/null
+++ b/sbe/sbefw/sbecmdscomaccess.C
@@ -0,0 +1,282 @@
+/*
+ * @file: ppe/sbe/sbefw/sbecmdscomaccess.C
+ *
+ * @brief This file contains the SBE SCOM Access chipOps
+ *
+ */
+
+#include "sbecmdscomaccess.H"
+#include "sbefifo.H"
+#include "sbe_sp_intf.H"
+#include "sbetrace.H"
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbeGetScom (uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbeGetScom "
+ SBE_ENTER(SBE_FUNC);
+
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+
+ do
+ {
+ uint16_t l_primStatus = g_sbeCmdRespHdr.prim_status;
+ uint16_t l_secStatus = g_sbeCmdRespHdr.sec_status ;
+
+ // Will attempt to dequeue two entries for
+ // the scom addresses plus the expected
+ // EOT entry at the end
+
+ // @TODO via RTC : 130575
+ // Optimize both the RC handling and
+ // FIFO operation infrastructure.
+ uint8_t l_len2dequeue = 3;
+ uint32_t l_scomAddr[3] = {0};
+ l_rc = sbeUpFifoDeq_mult (l_len2dequeue, &l_scomAddr[0]);
+
+ // If FIFO access failure
+ if (l_rc == SBE_SEC_FIFO_ACCESS_FAILURE)
+ {
+ // Let command processor routine to handle the RC.
+ break;
+ }
+
+ // If we didn't receive EOT yet
+ if ( (l_rc != SBE_FIFO_RC_EOT_ACKED) &&
+ (l_rc != SBE_FIFO_RC_EOT_ACK_FAILED) )
+ {
+ // We must have received unexpected data
+ // on the upstream FIFO.
+
+ // Flush upstream FIFO until EOT;
+ l_len2dequeue = 1;
+ l_rc = sbeUpFifoDeq_mult ( l_len2dequeue, NULL, true );
+
+ // We will break out here to force
+ // command processor routine to handle the RC.
+ // If the RC indicates the receipt of EOT,
+ // It would send the appropriate response
+ // back into the down stream FIFO.
+ // For all other failures, it would force
+ // timeout the chipOp operation
+ break;
+ }
+
+ // If EOT arrived prematurely
+ if ( ((l_rc == SBE_FIFO_RC_EOT_ACKED) ||
+ (l_rc == SBE_FIFO_RC_EOT_ACK_FAILED))
+ && (l_len2dequeue < 2) )
+ {
+ // We will break out here to force
+ // command processor routine to respond
+ // into the downstream FIFO with
+ // primary response code as SBE_PRI_INVALID_DATA
+ break;
+ }
+
+ uint32_t l_sbeDownFifoRespBuf[6] = {0};
+ uint32_t l_pcbpibStatus = SBE_PCB_PIB_ERROR_NONE;
+ uint8_t l_len2enqueue = 0;
+ uint8_t l_index = 0;
+ // successfully dequeued two entries for
+ // scom address followed by the EOT entry
+ if ( ((l_rc == SBE_FIFO_RC_EOT_ACKED) ||
+ (l_rc == SBE_FIFO_RC_EOT_ACK_FAILED))
+ && (l_len2dequeue == 2) )
+ {
+ // @TODO via RTC : 126140
+ // Support Indirect SCOM
+ // Data entry 1 : Scom Register Address (0..31)
+ // Data entry 2 : Register Address (32..63)
+ // For Direct SCOM, will ignore entry 1
+
+ uint64_t l_scomData = 0;
+ SBE_TRACE(SBE_FUNC"scomAddr1[0x%08X]", l_scomAddr[1]);
+ l_rc = getscom (0, l_scomAddr[1], &l_scomData);
+
+ if (l_rc) // scom failed
+ {
+ SBE_ERROR(SBE_FUNC"getscom failed, l_rc[0x%08X]", l_rc);
+ l_primStatus = SBE_PRI_GENERIC_EXECUTION_FAILURE;
+ l_secStatus = SBE_SEC_GENERIC_FAILURE_IN_EXECUTION;
+ l_pcbpibStatus = l_rc;
+ }
+
+ if (!l_rc) // successful scom
+ {
+ SBE_TRACE(SBE_FUNC"getscom succeeds, l_scomData[0x%X]",
+ l_scomData);
+
+ l_sbeDownFifoRespBuf[0] = (uint32_t)(l_scomData>>32);
+ l_sbeDownFifoRespBuf[1] = (uint32_t)(l_scomData);
+
+ // Push the data into downstream FIFO
+ l_len2enqueue = 2;
+ l_rc = sbeDownFifoEnq_mult (l_len2enqueue,
+ &l_sbeDownFifoRespBuf[0]);
+ if (l_rc)
+ {
+ // will let command processor routine
+ // handle the failure
+ break;
+ }
+ l_index = 2;
+ } // end successful scom
+ } // end successful dequeue
+
+ // Build the response header packet
+
+ uint8_t l_curIndex = l_index ;
+ sbeBuildMinRespHdr(&l_sbeDownFifoRespBuf[0],
+ l_curIndex,
+ l_primStatus,
+ l_secStatus,
+ l_pcbpibStatus,
+ l_index);
+
+ // Now enqueue into the downstream FIFO
+ l_len2enqueue = ++l_curIndex - l_index;
+ l_rc = sbeDownFifoEnq_mult (l_len2enqueue,
+ &l_sbeDownFifoRespBuf[l_index]);
+ if (l_rc)
+ {
+ // will let command processor routine
+ // handle the failure
+ break;
+ }
+
+ } while(false);
+
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+/////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbePutScom (uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbePutScom "
+ SBE_ENTER(SBE_FUNC);
+
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+
+ do
+ {
+ uint16_t l_primStatus = g_sbeCmdRespHdr.prim_status;
+ uint16_t l_secStatus = g_sbeCmdRespHdr.sec_status ;
+
+ // Will attempt to dequeue four entries for
+ // the scom address (two entries) and the
+ // corresponding data (two entries) plus
+ // the expected EOT entry at the end
+
+ // @TODO via RTC : 130575
+ // Optimize both the RC handling and
+ // FIFO operation infrastructure.
+ uint8_t l_len2dequeue = 5;
+ uint32_t l_scomAddr_Data[5] = {0};
+ l_rc = sbeUpFifoDeq_mult (l_len2dequeue, &l_scomAddr_Data[0]);
+
+ // If FIFO access failure
+ if (l_rc == SBE_SEC_FIFO_ACCESS_FAILURE)
+ {
+ // Let command processor routine to handle the RC.
+ break;
+ }
+
+ // If we didn't receive EOT yet
+ if ( (l_rc != SBE_FIFO_RC_EOT_ACKED) &&
+ (l_rc != SBE_FIFO_RC_EOT_ACK_FAILED) )
+ {
+ // We must have received unexpected data
+ // on the upstream FIFO.
+
+ // Flush upstream FIFO until EOT;
+ l_len2dequeue = 1;
+ l_rc = sbeUpFifoDeq_mult ( l_len2dequeue, NULL, true );
+
+ // We will break out here to force
+ // command processor routine to handle the RC.
+ // If the RC indicates the receipt of EOT,
+ // It would send the appropriate response
+ // back into the down stream FIFO.
+ // For all other failures, it would force
+ // timeout the chipOp operation
+ break;
+ }
+
+ // If EOT arrived prematurely
+ if ( ((l_rc == SBE_FIFO_RC_EOT_ACKED) ||
+ (l_rc == SBE_FIFO_RC_EOT_ACK_FAILED))
+ && (l_len2dequeue < 4) )
+ {
+ // We will break out here to force
+ // command processor routine to respond
+ // into the downstream FIFO with
+ // primary response code as SBE_PRI_INVALID_DATA
+ break;
+ }
+
+ uint64_t l_scomData = 0;
+ uint32_t l_sbeDownFifoRespBuf[4] = {0};
+ uint32_t l_pcbpibStatus = SBE_PCB_PIB_ERROR_NONE;
+ uint8_t l_len2enqueue = 0;
+ // successfully dequeued two entries for
+ // scom address followed by the EOT entry
+ if ( ((l_rc == SBE_FIFO_RC_EOT_ACKED) ||
+ (l_rc == SBE_FIFO_RC_EOT_ACK_FAILED))
+ && (l_len2dequeue == 4) )
+ {
+ // @TODO via RTC : 126140
+ // Support Indirect SCOM
+ // Data entry 1 : Scom Register Address (0..31)
+ // Data entry 2 : Scom Register Address (32..63)
+ // Data entry 3 : Scom Register Data (0..31)
+ // Data entry 4 : Scom Register Data (32..63)
+ // For Direct SCOM, will ignore entry 1
+ l_scomData = ((uint64_t)(l_scomAddr_Data[2])<<32)
+ | (l_scomAddr_Data[3]);
+
+ SBE_DEBUG(SBE_FUNC"scomAddr0[0x%X]"
+ "scomAddr1[0x%X]"
+ "scomData0[0x%X]"
+ "scomData1[0x%X]",
+ l_scomAddr_Data[0], l_scomAddr_Data[1],
+ l_scomAddr_Data[2], l_scomAddr_Data[3]);
+
+ l_rc = putscom (0, l_scomAddr_Data[1], l_scomData);
+
+ if (l_rc) // scom failed
+ {
+ SBE_ERROR(SBE_FUNC"putscom failed, l_rc[0x%08X]", l_rc);
+ l_primStatus = SBE_PRI_GENERIC_EXECUTION_FAILURE;
+ l_secStatus = SBE_SEC_GENERIC_FAILURE_IN_EXECUTION;
+ l_pcbpibStatus = l_rc;
+ }
+ } // end successful dequeue
+
+ // Build the response header packet
+
+ uint8_t l_curIndex = 0;
+ sbeBuildMinRespHdr(&l_sbeDownFifoRespBuf[0],
+ l_curIndex,
+ l_primStatus,
+ l_secStatus,
+ l_pcbpibStatus);
+
+ // Now enqueue into the downstream FIFO
+ l_len2enqueue = ++l_curIndex;
+ l_rc = sbeDownFifoEnq_mult (l_len2enqueue, &l_sbeDownFifoRespBuf[0]);
+ if (l_rc)
+ {
+ // will let command processor routine
+ // handle the failure
+ break;
+ }
+
+ } while(false);
+
+ return l_rc;
+ #undef SBE_FUNC
+}
diff --git a/sbe/sbefw/sbecmdscomaccess.H b/sbe/sbefw/sbecmdscomaccess.H
new file mode 100644
index 00000000..aba4c2ab
--- /dev/null
+++ b/sbe/sbefw/sbecmdscomaccess.H
@@ -0,0 +1,35 @@
+/*
+ * @file: ppe/sbe/sbefw/sbecmdscomaccess.H
+ *
+ * @brief This file contains the Interfaces for the SCOM Access chip-ops
+ *
+ */
+
+#ifndef __SBEFW_SBECMDSCOMACCESS_H
+#define __SBEFW_SBECMDSCOMACCESS_H
+
+#include <stdint.h>
+
+/**
+ * @brief sbeDownFifoGetStatus : Write data into Downstream FIFO
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeGetScom (uint8_t *i_pArg);
+
+
+/**
+ * @brief sbeDownFifoGetStatus : Write data into Downstream FIFO
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbePutScom (uint8_t *i_pArg);
+
+
+
+
+#endif /* __SBEFW_SBECMDSCOMACCESS_H */
diff --git a/sbe/sbefw/sbeexeintf.H b/sbe/sbefw/sbeexeintf.H
new file mode 100644
index 00000000..f70f8c20
--- /dev/null
+++ b/sbe/sbefw/sbeexeintf.H
@@ -0,0 +1,171 @@
+/*
+ * @file: ppe/sbe/sbefw/sbeexeintf.H
+ *
+ * @brief This file contains the SBE control loop firmware details like
+ * - Thread priority enums
+ * - Thread stack size and space enums
+ * - Thread sub-rountine declarations
+ * - IRQ setup and ISR declarations
+ * - Other Common declaration among all the threads
+ */
+
+#ifndef __SBEFW_SBE_H
+#define __SBEFW_SBE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "pk.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @brief enums for priorities for thread creation
+ *
+ */
+typedef enum
+{
+ THREAD_PRIORITY_MAX_0,
+ THREAD_PRIORITY_1,
+ THREAD_PRIORITY_2,
+ THREAD_PRIORITY_3,
+ THREAD_PRIORITY_4,
+ THREAD_PRIORITY_5,
+ THREAD_PRIORITY_6,
+ THREAD_PRIORITY_7,
+ THREAD_PRIORITY_8,
+ THREAD_PRIORITY_MIN_30 = 30,
+} sbeThreadPriorities ;
+
+/**
+ * @brief enums for thread stack sizes
+ * - Non-Critical Stack used by non-critical interrupt handlers
+ * - Critical Stack used for critical interrupts
+ * - Stacks for each thread
+ *
+ * @TODO via RTC : 128657
+ * - Measure the actual thread stack utilization
+ * - This will be a continuous activity
+ */
+enum sbeThreadStackSize
+{
+ SBE_NONCRITICAL_STACK_SIZE = 256,
+ SBE_THREAD_ASYNC_CMD_PROC_STACK_SIZE = 256,
+ SBE_THREAD_CMD_RECV_STACK_SIZE = 512,
+ SBE_THREAD_SYNC_CMD_PROC_STACK_SIZE = 2048,
+};
+
+/**
+ * @brief enums SBE internal error codes
+ *
+*/
+enum sbeInternalResponseCodes
+{
+ SBE_FIFO_RESET_RECEIVED = 0xFA,
+ SBE_FIFO_RESET_HANDLING_FAILED = 0xFB,
+ SBE_FUNC_NOT_SUPPORTED = 0xFC,
+};
+
+/**
+ * @brief Global semaphore : g_sbeSemCmdRecv
+ *
+ * This is used to synchronize between the ISR and
+ * the command receiver thread.
+ *
+ */
+extern PkSemaphore g_sbeSemCmdRecv;
+
+/**
+ * @brief Global semaphore : g_sbeSemCmdProcess
+ *
+ * This is used to synchronize between command receiver thread
+ * and synchronous command processor thread.
+ *
+ */
+extern PkSemaphore g_sbeSemCmdProcess;
+
+/**
+ * @brief Global semaphore : g_sbeSemFifoReset
+ *
+ * This is used to synchronize the graceful handling of FIFO reset
+ * between command receiver and synchronous command processor threads.
+ *
+ */
+extern PkSemaphore g_sbeSemFifoReset;
+
+/**
+ * @TODO via RTC : 128658
+ * Mutex protect the critical data
+ * e.g., add Mutex g_sbeMutCmdReqBuf etc.
+ */
+
+/**
+ * @brief sbeCommandReceiver_routine
+ * The major responsibilities of this thread are :
+ * - Determine the reason for the interrupt
+ * - FIFO New data
+ * - FIFO reset
+ * - Host services
+ * - Dequeue the mandatory 2 entry header from upstream FIFO
+ * - Command input data validation
+ * - SBE State and pre-requirements validation
+ * - FFDC collection and FIFO flush upon validation failure
+ * - Unblock SBE command processor thread
+ * - Perform FIFO reset upon request from SP
+ *
+ * @param[in] i_pArg - Any buffer needed to be passed to the thread routine
+ */
+void sbeCommandReceiver_routine(void *i_pArg);
+
+/**
+ * @brief sbeSyncCommandProcessor_routine
+ * The major responsibilities of this thread are :
+ * - Dequeue data payload from upstream FIFO
+ * - Un-marshalling of the command request data
+ * - Blacklist validation
+ * - FFDC collection upon validation failure
+ * - Invoke the corresponding Hardware access utility
+ * or the HWP corresponding to the chipOp request
+ * - FFDC collection and FIFO flush upon hardware access / HWP failure
+ * - Build the response buffer with the data and the header
+ * - Enqueue the response into the Downstream FIFO
+ * - Un-mask the new data available interrupt
+ *
+ * @param[in] i_pArg - Any buffer needed to be passed to the thread routine
+ */
+void sbeSyncCommandProcessor_routine(void *i_pArg);
+
+/**
+ * @brief sbeAsyncCommandProcessor_routine
+ * @TODO RTC via : 130392
+ * Add infrastructure for host interface
+ *
+ * @param[in] i_pArg - Any buffer needed to be passed to the thread routine
+ */
+void sbeAsyncCommandProcessor_routine(void *i_pArg);
+
+
+/* @brief ISR for all application FIFO Interrupts
+ * - FIFO : New data available
+ * - FIFO : Reset Request
+ *
+ * @param[in/out] i_pArg - Any buffer needed to be passed to the handler
+ * @param[in] i_irq - IRQ number as defined in the SBE PPE spec
+ */
+void sbe_fifo_interrupt_handler(void* i_pArg, PkIrqId i_irq);
+
+
+/* brief : Register SBE interrupt handlers and enable the IRQs
+ *
+ * @return int PK_OK - Success (IRQ Setup was successful)
+ * PK_INVALID_ARGUMENT_IRQ_HANDLER - Invalid argument passed
+ * (Code bug)
+ *
+ */
+int sbeIRQSetup (void);
+
+
+#endif /* __SBEFW_SBE_H */
diff --git a/sbe/sbefw/sbefifo.C b/sbe/sbefw/sbefifo.C
new file mode 100644
index 00000000..08a493db
--- /dev/null
+++ b/sbe/sbefw/sbefifo.C
@@ -0,0 +1,250 @@
+/*
+ * @file: ppe/sbe/sbefw/sbefifo.C
+ *
+ * @brief This file contains the SBE FIFO Commands
+ *
+ */
+
+#include "sbeexeintf.H"
+#include "sbefifo.H"
+#include "sbetrace.H"
+#include "sbe_sp_intf.H"
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbeUpFifoDeq_mult (uint8_t &io_len,
+ uint32_t *o_pData,
+ const bool i_flush)
+{
+ #define SBE_FUNC " sbeUpFifoDeq_mult "
+ uint32_t l_rc = SBE_FIFO_RC_UNKNOWN;
+ uint8_t l_len = 0;
+
+ // @TODO via RTC : 130575
+ // Refactor this utility to
+ // optimize RC handling, stack usage
+ // and FIFO operation infrastructure.
+ //
+
+ do
+ {
+ sbe_upfifo_entry_t l_data = {0};
+ uint64_t l_upfifo_data = 0;
+
+ // Read Double word from the Upstream FIFO;
+ // The DW data represents the first 32 bits of data word entry
+ // followed by the status bits.
+
+ // Bit 0-31 : Data
+ // Bit 32 : Data valid flag
+ // Bit 33 : EOT flag
+ // Bit 34-63 : Status (2-31)
+ // Valid : EOT
+ // 1 : 0 -> data=message
+ // 0 : 1 -> data=dummy_data of EOT operation
+ // 0 : 0 -> data=dummy_data
+ // 1 : 1 -> Not used
+
+ l_rc = sbeUpFifoDeq ( &l_upfifo_data );
+
+ if (l_rc)
+ {
+ // Error while dequeueing from upstream FIFO
+ SBE_ERROR(SBE_FUNC"sbeUpFifoDeq failed,"
+ "l_rc=[0x%08X]", l_rc);
+ l_rc = SBE_SEC_FIFO_ACCESS_FAILURE;
+ break;
+ }
+
+ l_data.upfifo_data = (uint32_t)(l_upfifo_data>>32);
+ l_data.upfifo_status.upfifo_status_uint32 = (uint32_t)
+ (l_upfifo_data);
+
+ SBE_DEBUG(SBE_FUNC"sbeUpFifoDeq, "
+ "l_data.upfifo_data=[0x%08X],"
+ "l_data.upfifo_status=[0x%08X]",
+ l_data.upfifo_data,
+ l_data.upfifo_status.upfifo_status_uint32);
+
+ // If FIFO reset is requested
+ if(l_data.upfifo_status.upfifo_status_bitset.req_upfifo_reset)
+ {
+ // @TODO via RTC : 126147
+ // Review reset loop flow in here.
+ // Received a FIFO reset request
+ l_rc = SBE_FIFO_RC_RESET;
+ break;
+ }
+
+ // if EOT flag is set
+ // clear EOT
+ if (l_data.upfifo_status.upfifo_status_bitset.eot_flag)
+ {
+ l_rc = sbeUpFifoAckEot();
+ if (l_rc)
+ {
+ // Error while ack'ing EOT in upstream FIFO
+ SBE_ERROR(SBE_FUNC"sbeUpFifoAckEot failed,"
+ "l_rc=[0x%08X]", l_rc);
+ // Collect FFDC
+ l_rc = SBE_FIFO_RC_EOT_ACK_FAILED;
+ }
+ else
+ {
+ l_rc = SBE_FIFO_RC_EOT_ACKED;
+ }
+ break;
+ }
+
+ // if Upstream FIFO is empty,
+ if (l_data.upfifo_status.upfifo_status_bitset.fifo_empty)
+ {
+ l_rc = SBE_FIFO_RC_EMPTY;
+ continue;
+ }
+
+ if (i_flush)
+ {
+ l_len = 0; // to force the upFIFO flush until EOT arrives
+ continue;
+ }
+
+ o_pData[l_len] = l_data.upfifo_data;
+ ++l_len;
+ l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+
+ } while(l_len<io_len);
+
+ // Return the length of entries dequeued.
+ // When user sets i_flush as true, this
+ // would return io_len as 0;
+ io_len = l_len;
+ return l_rc;
+
+ #undef SBE_FUNC
+}
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbeDownFifoEnq_mult (uint8_t &io_len,
+ const uint32_t *i_pData)
+{
+ #define SBE_FUNC " sbeDownFifoEnq_mult "
+ uint8_t l_rc = SBE_FIFO_RC_UNKNOWN;
+ uint8_t l_len = 0;
+
+ // @TODO via RTC : 130575
+ // Refactor this utility to
+ // optimize RC handling, stack usage
+ // and FIFO operation infrastructure.
+
+ do
+ {
+ sbe_downfifo_status_t l_downFifoStatus ;
+ typedef union
+ {
+ uint64_t status;
+ uint64_t data;
+ } sbeDownFiFoEntry_t;
+ sbeDownFiFoEntry_t l_sbeDownFiFoEntry ;
+
+ // Read the down stream FIFO status
+ l_rc = sbeDownFifoGetStatus (&l_sbeDownFiFoEntry.status);
+ if (l_rc)
+ {
+ // Error while reading downstream FIFO status
+ SBE_ERROR(SBE_FUNC"sbeDownFifoGetStatus failed, "
+ "l_rc=[0x%08X]", l_rc);
+ l_rc = SBE_SEC_FIFO_ACCESS_FAILURE;
+ break;
+ }
+
+ l_downFifoStatus.downfifo_status_uint32 = (uint32_t)
+ (l_sbeDownFiFoEntry.status>>32);
+
+ SBE_DEBUG(SBE_FUNC"downstream fifo status[0x%08X]",
+ l_downFifoStatus.downfifo_status_uint32);
+
+ // Check if there was a FIFO reset request from SP
+ if (l_downFifoStatus.downfifo_status_bitset.req_upfifo_reset)
+ {
+ // @TODO via RTC : 126147
+ // Review reset loop flow in here.
+ // Received an upstream FIFO reset request
+ SBE_ERROR(SBE_FUNC"Received reset request");
+ l_rc = SBE_FIFO_RC_RESET;
+ break;
+ }
+
+ // Check if downstream FIFO is full
+ if (l_downFifoStatus.downfifo_status_bitset.fifo_full)
+ {
+ // Downstream FIFO is full
+ SBE_INFO(SBE_FUNC"Downstream FIFO is full");
+ l_rc = SBE_FIFO_RC_FULL; // in case we ever add timeout
+ continue;
+ }
+
+ // PIB write data format:
+ // Bit 0 - 31 : Data
+ // Bit 32 - 63 : Unused
+
+ l_sbeDownFiFoEntry.data = (uint64_t)(*(i_pData+l_len));
+ l_sbeDownFiFoEntry.data = l_sbeDownFiFoEntry.data<<32;
+
+ SBE_DEBUG(SBE_FUNC"Downstream fifo data entry[0x%08X]",
+ (l_sbeDownFiFoEntry.data>>32));
+
+ // Write the data into the downstream FIFO
+ l_rc = sbeDownFifoEnq (l_sbeDownFiFoEntry.data);
+ if (l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"sbeDownFifoEnq failed, "
+ "l_rc[0x%08X]", l_rc);
+ l_rc = SBE_SEC_FIFO_ACCESS_FAILURE;
+ break;
+ }
+
+ l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ ++l_len;
+
+ } while(l_len<io_len);
+
+ io_len = l_len;
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////
+void sbeBuildMinRespHdr ( uint32_t *io_pBuf,
+ uint8_t &io_curIndex,
+ const uint16_t i_primStatus,
+ const uint16_t i_secStatus,
+ const uint32_t i_pcbpibStatus,
+ const uint8_t i_startIndex )
+{
+ do
+ {
+ if (!io_pBuf)
+ {
+ break;
+ }
+
+ io_pBuf[io_curIndex] = sbeBuildRespHeaderMagicCodeCmdClass();
+ io_pBuf[++io_curIndex] = sbeBuildRespHeaderStatusWordLocal(
+ i_primStatus, i_secStatus);
+
+ // @TODO via RTC: 128916
+ // pcb-pib error is optional,
+ // not needed for success case
+ io_pBuf[++io_curIndex] = i_pcbpibStatus;
+
+ // Somehow this compiler isn't allowing the
+ // index pre-increment for the last array entry
+ // directly embedded into the assignment
+ ++io_curIndex;
+ io_pBuf[io_curIndex] = io_curIndex - i_startIndex + 1;
+
+ } while(false);
+}
diff --git a/sbe/sbefw/sbefifo.H b/sbe/sbefw/sbefifo.H
new file mode 100644
index 00000000..e9a815b0
--- /dev/null
+++ b/sbe/sbefw/sbefifo.H
@@ -0,0 +1,356 @@
+/*
+ * @file: ppe/sbe/sbefw/sbefifo.H
+ *
+ * @brief This file contains the SBE FIFO Commands
+ *
+ */
+
+#ifndef __SBEFW_SBEFIFO_H
+#define __SBEFW_SBEFIFO_H
+
+#include "sbeexeintf.H"
+#include "sbetrace.H"
+#include "ppe42_scom.h"
+
+/**
+ * @brief SBE FIFO Access addresses
+ *
+ */
+const uint32_t SBE_FIFO_BASE = 0x000B0000;
+
+const uint32_t SBE_UPSTREAM_FIFO_DEQ_ADD = SBE_FIFO_BASE + 0x0000;
+const uint32_t SBE_UPSTREAM_FIFO_STATUS = SBE_FIFO_BASE + 0x0001;
+const uint32_t SBE_UPSTREAM_FIFO_SIGNAL_EOT = SBE_FIFO_BASE + 0x0002;
+const uint32_t SBE_UPSTREAM_FIFO_REQ_RESET = SBE_FIFO_BASE + 0x0003;
+const uint32_t SBE_UPSTREAM_FIFO_PERFORM_RESET = SBE_FIFO_BASE + 0x0004;
+const uint32_t SBE_UPSTREAM_FIFO_ACK_EOT = SBE_FIFO_BASE + 0x0005;
+
+const uint32_t SBE_DOWNSTREAM_FIFO_ENQ_ADD = SBE_FIFO_BASE + 0x0010;
+const uint32_t SBE_DOWNSTREAM_FIFO_STATUS = SBE_FIFO_BASE + 0x0011;
+const uint32_t SBE_DOWNSTREAM_FIFO_SIGNAL_EOT = SBE_FIFO_BASE + 0x0012;
+const uint32_t SBE_DOWNSTREAM_FIFO_REQ_RESET = SBE_FIFO_BASE + 0x0013;
+const uint32_t SBE_DOWNSTREAM_FIFO_PERFORM_RESET = SBE_FIFO_BASE + 0x0014;
+const uint32_t SBE_DOWNSTREAM_FIFO_ACK_EOT = SBE_FIFO_BASE + 0x0015;
+
+/**
+ * @brief SBE Upstream FIFO Status bits
+ *
+ */
+
+typedef struct
+{
+ uint32_t valid_flag:1; // Bit 0
+ uint32_t eot_flag:1; // Bit 1
+ uint32_t parity_err:1; // Bit 2
+ uint32_t reserved3_5:3; // Bit 3:5
+ uint32_t req_upfifo_reset:1; // Bit 6
+ uint32_t req_downfifo_reset:1; // Bit 7
+ uint32_t signaling_eot:1; // Bit 8
+ uint32_t reserved9:1; // Bit 9
+ uint32_t fifo_full:1; // Bit 10
+ uint32_t fifo_empty:1; // Bit 11
+ uint32_t fifo_entry_count:4; // Bit 12:15
+ uint32_t fifo_valid_flags:8; // Bit 16:23
+ uint32_t fifo_eot_flags:8; // Bit 24:31
+
+} sbe_upfifo_status_bitset_t ;
+
+typedef union
+{
+ sbe_upfifo_status_bitset_t upfifo_status_bitset;
+ uint32_t upfifo_status_uint32;
+} sbe_upfifo_status_t;
+
+
+/**
+ * @brief 64-bit DW structure for Upstream FIFO Read
+ *
+ */
+typedef struct
+{
+ uint32_t upfifo_data;
+ sbe_upfifo_status_t upfifo_status;
+} sbe_upfifo_entry_t ;
+
+
+/**
+ * @brief SBE Downstream FIFO Status bits
+ *
+ */
+typedef struct
+{
+ uint32_t reserved0_1:2; // Bit 0:1
+ uint32_t parity_err:1; // Bit 2
+ uint32_t reserved3_5:3; // Bit 3:5
+ uint32_t req_downfifo_reset:1; // Bit 6
+ uint32_t req_upfifo_reset:1; // Bit 7
+ uint32_t signaling_eot:1; // Bit 8
+ uint32_t reserved9:1; // Bit 9
+ uint32_t fifo_full:1; // Bit 10
+ uint32_t fifo_empty:1; // Bit 11
+ uint32_t fifo_entry_count:4; // Bit 12:15
+ uint32_t fifo_valid_flags:8; // Bit 16:23
+ uint32_t fifo_eot_flags:8; // Bit 24:31
+
+} sbe_downfifo_status_bitset_t ;
+
+typedef union
+{
+ sbe_downfifo_status_bitset_t downfifo_status_bitset;
+ uint32_t downfifo_status_uint32;
+} sbe_downfifo_status_t;
+
+
+/**
+ * @brief Command Request Header
+ *
+ */
+typedef struct
+{
+ uint32_t cmdReqHdr_cmdLen ;
+ uint32_t cmdReqHdr_cmdClass ;
+} sbeCmdHdr_t;
+
+extern sbeCmdHdr_t g_sbeCmdHdr;
+
+
+/**
+ * @brief Command response structure to hold the primary and secondary
+ * status values. This will be utilized when a command class
+ * validation or state machine check fails.
+ *
+ */
+typedef struct
+{
+ uint16_t prim_status ; // Primary Response Status
+ uint16_t sec_status ; // Secondary Response Status
+} sbeCmdRespHdr_t;
+
+extern sbeCmdRespHdr_t g_sbeCmdRespHdr;
+
+typedef struct
+{
+ uint16_t magic_bytes;
+ uint16_t len;
+} sbeCmdResp_FFDC_t;
+
+/**
+ * @brief FIFO access return codes for internal purpose
+ *
+ */
+typedef enum
+{
+ SBE_FIFO_RC_ACCESS_SUCCESS = 0,
+ SBE_FIFO_RC_RESET = 0xE0,
+ SBE_FIFO_RC_FULL,
+ SBE_FIFO_RC_EMPTY,
+ SBE_FIFO_RC_DUMMY_DATA,
+ SBE_FIFO_RC_EOT_ACKED,
+ SBE_FIFO_RC_EOT_ACK_FAILED,
+ SBE_FIFO_RC_UNKNOWN,
+} sbe_fifo_access_rc_t;
+
+
+/*****************************************************************/
+/** Upstream FIFO access utilities **/
+/*****************************************************************/
+
+/**
+ * @brief sbeUpFifoDeq : Read entry and status from Upstream FIFO
+ *
+ * @param[out] 64-Bit Data read from Upstream FIFO
+ *
+ * @return Rc from the underlying scom utility
+ *
+ */
+extern inline uint32_t sbeUpFifoDeq (uint64_t *o_data)
+{
+ /* For SBE FIFO (PIB) access, chiplet ID should be passed as 0 */
+ return getscom(0, SBE_UPSTREAM_FIFO_DEQ_ADD, o_data);
+}
+
+
+/**
+ * @brief sbeUpFifoPerformReset : Perform Upstream FIFO reset request
+ *
+ * @return Rc from the underlying scom utility
+ *
+ */
+extern inline uint32_t sbeUpFifoPerformReset (void)
+{
+ SBE_TRACE(">sbeUpFifoPerformReset");
+ return putscom(0, SBE_UPSTREAM_FIFO_PERFORM_RESET, ((uint64_t)0x1)<<32);
+}
+
+
+/**
+ * @brief sbeUpFifoAckEot : Acknowledge EOT in Upstream FIFO
+ *
+ * @return Rc from the underlying scom utility
+ *
+ */
+extern inline uint32_t sbeUpFifoAckEot (void)
+{
+ SBE_DEBUG("sbeUpFifoAckEot");
+
+ return putscom(0, SBE_UPSTREAM_FIFO_ACK_EOT, ((uint64_t)0x1)<<32);
+}
+
+
+/*****************************************************************/
+/** Downstream FIFO access utilities **/
+/*****************************************************************/
+
+/**
+ * @brief sbeDownFifoEnq : Write data into Downstream FIFO
+ *
+ * @param[in] 64-Bit Data write into Downstream FIFO
+ * Bit 0-31 : Data
+ * Bit 32-63 : Unused
+ *
+ * @return Rc from the underlying scom utility
+ */
+extern inline uint32_t sbeDownFifoEnq (const uint64_t i_data)
+{
+ SBE_DEBUG(">sbeDownFifoEnq");
+ return putscom(0, SBE_DOWNSTREAM_FIFO_ENQ_ADD, i_data);
+}
+
+
+/**
+ * @brief sbeDownFifoGetStatus : Read status from downstream FIFO
+ *
+ * @param[out] 64-Bit Read status from downstream FIFO
+ * Bit 0-31 : Data
+ * Bit 32-63 : Unused
+ *
+ * @return Rc from the underlying scom utility
+ */
+extern inline uint32_t sbeDownFifoGetStatus (uint64_t *o_data)
+{
+ SBE_DEBUG(">sbeDownFifoStatus");
+ return getscom(0, SBE_DOWNSTREAM_FIFO_STATUS, o_data);
+}
+
+/**
+ * @brief sbeDownFifoSignalEot : Signal EOT in Downstream FIFO
+ *
+ * @return Rc from the underlying scom utility
+ *
+ */
+extern inline uint32_t sbeDownFifoSignalEot (void)
+{
+ SBE_DEBUG(">sbeDownFifoSignalEot");
+ return putscom(0, SBE_DOWNSTREAM_FIFO_SIGNAL_EOT, ((uint64_t)0x1)<<32);
+}
+
+
+/**********************************************************************/
+// Utilities
+/**********************************************************************/
+
+/**
+ * @brief sbeUpFifoDeq_mult : Dequeue multiple entries from upstream FIFO
+ *
+ * @param[in/out] io_len
+ * number of entries to dequeue as input,
+ * number of entries dequeued as output without
+ * taking EOT dummy entry into consideration
+ * @param[out] o_pData entries dequeued into the buffer
+ * @param[in] i_flush true / false
+ * true - caller requested FIFO flush,
+ * io_len would be returned as 0
+ * false - default case,
+ * io_len would be number of entries dequeued
+ *
+ * @return Rc from the underlying scom utility
+ *
+ */
+extern uint32_t sbeUpFifoDeq_mult (uint8_t &io_len,
+ uint32_t *o_pData,
+ const bool i_flush = false);
+
+
+/**
+ * @brief sbeDownFifoEnq_mult : Enqueue into downstream FIFO
+ *
+ * @param[in/out] io_len number of entries to enqueue as input,
+ * number of entries enqueued as output
+ * @param[in] i_pData buffer containting data to be enqueued
+ *
+ * @return Rc from the underlying scom utility
+ *
+ */
+extern uint32_t sbeDownFifoEnq_mult (uint8_t &io_len,
+ const uint32_t *i_pData) ;
+
+
+/**
+ * @brief sbeBuildRespHeaderMagicCodeCmdClass
+ * Builds the header word containing the magic code,
+ * the command class and the opcode
+ *
+ * @return Returns the header word in the response header
+ * containing the magic code, command class and opcode
+ *
+ */
+extern inline uint32_t sbeBuildRespHeaderMagicCodeCmdClass (void)
+{
+ return ( 0xC0DE0000 | g_sbeCmdHdr.cmdReqHdr_cmdClass );
+}
+
+/**
+ * @brief sbeBuildRespHeaderStatusWordGlobal
+ * Builds the status header word from global variables
+ *
+ * @return Returns the status word in the response header
+ *
+ */
+extern inline uint32_t sbeBuildRespHeaderStatusWordGlobal (void)
+{
+ return ( (((uint32_t)g_sbeCmdRespHdr.prim_status)<<16) |
+ (g_sbeCmdRespHdr.sec_status) );
+}
+
+/**
+ * @brief sbeBuildRespHeaderStatusWordLocal
+ * Builds the status header word from passed in parameters
+ *
+ * @param[in] const uint16_t i_primStatus Primary Response Status Code
+ * @param[in] const uint16_t i_secStatus Secondary Response Status Code
+ *
+ * @return Returns the status word in the response header
+ *
+ */
+extern inline uint32_t sbeBuildRespHeaderStatusWordLocal (
+ const uint16_t i_primStatus,
+ const uint16_t i_secStatus)
+{
+ return ( (((uint32_t)i_primStatus)<<16) | (i_secStatus) );
+}
+
+/**
+ * @brief sbeBuildMinRespHdr : Builds minimum response header
+ *
+ * @desc This builds the buffer with the following status words
+ * - Magic Bytes, Command Class, Command opcode
+ * - Primary Status Code, Secondary Status Code
+ * - PCB / PIB Status Code [optional]
+ * - Distance to Status Header
+ * @param[in/out] uint32_t *io_pBuf Buffer to be filled in
+ * @param[in/out] uint8_t &io_curIndex Current Index into the buffer
+ * @param[in] const uint16_t i_primStatus Primary Response Status Code
+ * @param[in] const uint16_t i_secStatus Secondary Response Status Code
+ * @param[in] const uint32_t i_pcbpibStatus PCB-PIB Response Status Code
+ * @param[in] const uint8_t i_startIndex Starting Index into the buffer
+ */
+
+void sbeBuildMinRespHdr ( uint32_t *io_pBuf,
+ uint8_t &io_curIndex,
+ const uint16_t i_primStatus,
+ const uint16_t i_secStatus,
+ const uint32_t i_pcbpibStatus,
+ const uint8_t i_startIndex = 0 );
+
+
+#endif // __SBEFW_SBEFIFO_H
diff --git a/sbe/sbefw/sbeirq.C b/sbe/sbefw/sbeirq.C
new file mode 100644
index 00000000..3aa92188
--- /dev/null
+++ b/sbe/sbefw/sbeirq.C
@@ -0,0 +1,104 @@
+/*
+ * @file: ppe/sbe/sbefw/sbeirq.C
+ *
+ * @brief This sets up and registers SBE ISRs
+ *
+ */
+
+#include "sbeexeintf.H"
+#include "sbeirq.H"
+#include "sbetrace.H"
+
+
+////////////////////////////////////////////////////////////////
+// @brief: SBE control loop ISR:
+// - FIFO new data available
+// - FIFO reset request
+//
+// @param[in] i_pArg - Unused
+// @param[in] i_irq - IRQ number as defined in sbeirq.h
+//
+////////////////////////////////////////////////////////////////
+void sbe_fifo_interrupt_handler (void *i_pArg, PkIrqId i_irq)
+{
+ #define SBE_FUNC " sbe_fifo_interrupt_handler "
+ SBE_ENTER(SBE_FUNC"i_irq=[0x%02X]",i_irq);
+
+ int l_rc = 0;
+ switch (i_irq)
+ {
+ case SBE_IRQ_SBEFIFO_DATA:
+ case SBE_IRQ_SBEFIFO_RESET:
+ // Mask the interrupt
+ pk_irq_disable(i_irq);
+
+ // Unblock the command receiver thread
+ l_rc = pk_semaphore_post(&g_sbeSemCmdRecv);
+ if (l_rc)
+ {
+ // If we received an error while posting the semaphore,
+ // unmask the interrupt back and assert
+ // @TODO via RTC : 129166
+ // Add support for ASSERT here
+ SBE_ERROR(SBE_FUNC"pk_semaphore_post failed, rc=[%d]", l_rc);
+ pk_irq_enable(i_irq);
+ }
+ break;
+
+ default:
+ SBE_ERROR(SBE_FUNC"Unknown IRQ, assert");
+ // @TODO via RTC : 129166
+ // Add support for ASSERT here
+ break;
+ }
+ #undef SBE_FUNC
+}
+
+////////////////////////////////////////////////////////////////
+// See sbeexeintf.h for more details
+////////////////////////////////////////////////////////////////
+int sbeIRQSetup (void)
+{
+ #define SBE_FUNC " sbeIRQSetup "
+ int l_rc = 0;
+
+ // Disable the relevant IRQs while we set them up
+ pk_irq_disable(SBE_IRQ_SBEFIFO_DATA);
+ pk_irq_disable(SBE_IRQ_SBEFIFO_RESET);
+
+ do
+ {
+ // Register the IRQ handler with PK
+
+ // FIFO New data available interrupt
+ l_rc = pk_irq_handler_set(SBE_IRQ_SBEFIFO_DATA,
+ sbe_fifo_interrupt_handler,
+ NULL);
+
+ if(l_rc)
+ {
+ SBE_ERROR (SBE_FUNC"pk_irq_handler_set failed, IRQ=[0x%02X], "
+ "rc=[%d]", SBE_IRQ_SBEFIFO_DATA, l_rc);
+ break;
+ }
+
+ // FIFO Reset request
+ l_rc = pk_irq_handler_set(SBE_IRQ_SBEFIFO_RESET,
+ sbe_fifo_interrupt_handler,
+ NULL);
+
+ if(l_rc)
+ {
+ SBE_ERROR (SBE_FUNC"pk_irq_handler_set failed, IRQ=[0x%02X], "
+ "rc=[%d]", SBE_IRQ_SBEFIFO_RESET, l_rc);
+ break;
+ }
+
+ // Enable the IRQ
+ pk_irq_enable(SBE_IRQ_SBEFIFO_RESET);
+ pk_irq_enable(SBE_IRQ_SBEFIFO_DATA);
+ } while(false);
+
+ return l_rc;
+ #undef SBE_FUNC
+}
diff --git a/sbe/sbefw/sbeirq.H b/sbe/sbefw/sbeirq.H
new file mode 100644
index 00000000..2fcdd082
--- /dev/null
+++ b/sbe/sbefw/sbeirq.H
@@ -0,0 +1,84 @@
+/*
+ * $file: ppe/sbe/sbefw/sbeirq.H
+ *
+ * @brief This file contains the SBE PPE Interrupt Request numbers
+ */
+
+#ifndef _SBE_IRQ_H
+#define _SBE_IRQ_H
+
+/**
+ * @brief SBE PPE IRQ numbers
+ *
+ */
+
+#define SBE_IRQ_START0 0 /* SBE Start Vector 0 */
+#define SBE_IRQ_START1 1 /* SBE Start Vector 1 */
+#define SBE_IRQ_INTR0 2 /* SBE Interrupt S0 */
+#define SBE_IRQ_INTR1 3 /* SBE Interrupt S1 */
+#define SBE_IRQ_DRTM_REQ 4 /* DRTM late launch request */
+#define SBE_IRQ_SBEFIFO_RESET 5 /* FIFO - Reset request from SE */
+#define SBE_IRQ_SBEFIFO_DATA 6 /* FIFO - Incoming Data Available */
+
+#define SBE_IRQ_RESERVED_7 7
+#define SBE_IRQ_RESERVED_8 8
+#define SBE_IRQ_RESERVED_9 9
+
+#define SBE_IRQ_RESERVED_10 10
+#define SBE_IRQ_RESERVED_11 11
+#define SBE_IRQ_RESERVED_12 12
+#define SBE_IRQ_RESERVED_13 13
+#define SBE_IRQ_RESERVED_14 14
+#define SBE_IRQ_RESERVED_15 15
+#define SBE_IRQ_RESERVED_16 16
+#define SBE_IRQ_RESERVED_17 17
+#define SBE_IRQ_RESERVED_18 18
+#define SBE_IRQ_RESERVED_19 19
+#define SBE_IRQ_RESERVED_20 20
+#define SBE_IRQ_RESERVED_21 21
+#define SBE_IRQ_RESERVED_22 22
+#define SBE_IRQ_RESERVED_23 23
+#define SBE_IRQ_RESERVED_24 24
+#define SBE_IRQ_RESERVED_25 25
+#define SBE_IRQ_RESERVED_26 26
+#define SBE_IRQ_RESERVED_27 27
+#define SBE_IRQ_RESERVED_28 28
+#define SBE_IRQ_RESERVED_29 29
+#define SBE_IRQ_RESERVED_30 30
+#define SBE_IRQ_RESERVED_31 31
+#define SBE_IRQ_RESERVED_32 32
+#define SBE_IRQ_RESERVED_33 33
+#define SBE_IRQ_RESERVED_34 34
+#define SBE_IRQ_RESERVED_35 35
+#define SBE_IRQ_RESERVED_36 36
+#define SBE_IRQ_RESERVED_37 37
+#define SBE_IRQ_RESERVED_38 38
+#define SBE_IRQ_RESERVED_39 39
+#define SBE_IRQ_RESERVED_40 40
+#define SBE_IRQ_RESERVED_41 41
+#define SBE_IRQ_RESERVED_42 42
+#define SBE_IRQ_RESERVED_43 43
+#define SBE_IRQ_RESERVED_44 44
+#define SBE_IRQ_RESERVED_45 45
+#define SBE_IRQ_RESERVED_46 46
+#define SBE_IRQ_RESERVED_47 47
+#define SBE_IRQ_RESERVED_48 48
+#define SBE_IRQ_RESERVED_49 49
+#define SBE_IRQ_RESERVED_50 50
+#define SBE_IRQ_RESERVED_51 51
+#define SBE_IRQ_RESERVED_52 52
+#define SBE_IRQ_RESERVED_53 53
+#define SBE_IRQ_RESERVED_54 54
+#define SBE_IRQ_RESERVED_55 55
+#define SBE_IRQ_RESERVED_56 56
+#define SBE_IRQ_RESERVED_57 57
+#define SBE_IRQ_RESERVED_58 58
+#define SBE_IRQ_RESERVED_59 59
+#define SBE_IRQ_RESERVED_60 60
+#define SBE_IRQ_RESERVED_61 61
+#define SBE_IRQ_RESERVED_62 62
+#define SBE_IRQ_RESERVED_63 63
+
+
+
+#endif //_SBE_IRQ_H
diff --git a/sbe/sbefw/sbemain.C b/sbe/sbefw/sbemain.C
new file mode 100644
index 00000000..f2403bff
--- /dev/null
+++ b/sbe/sbefw/sbemain.C
@@ -0,0 +1,265 @@
+
+/* @file: ppe/sbe/sbefw/sbemain.C
+ *
+ * @brief This file does the following
+ * - SBE Application Main entry point
+ * - PK initialization
+ * - Thread initialization
+ * - Semaphore initialization
+ * - IRQ setup
+ * - Scheduling of the threads and
+ * - Starting of the control loop code flow
+ *
+ */
+
+
+#include "sbeexeintf.H"
+#include "sbetrace.H"
+
+
+////////////////////////////////////////////////////////////////
+// @brief Global semaphores
+////////////////////////////////////////////////////////////////
+PkSemaphore g_sbeSemCmdRecv;
+PkSemaphore g_sbeSemCmdProcess;
+PkSemaphore g_sbeSemFifoReset;
+
+////////////////////////////////////////////////////////////////
+// @brief Stacks for Non-critical Interrupts and Threads
+////////////////////////////////////////////////////////////////
+uint8_t g_sbe_Kernel_NCInt_stack[SBE_NONCRITICAL_STACK_SIZE];
+uint8_t g_sbeCommandReceiver_stack[SBE_THREAD_CMD_RECV_STACK_SIZE];
+uint8_t g_sbeSyncCommandProcessor_stack[SBE_THREAD_SYNC_CMD_PROC_STACK_SIZE];
+uint8_t g_sbeAsyncCommandProcessor_stack[SBE_THREAD_ASYNC_CMD_PROC_STACK_SIZE];
+
+////////////////////////////////////////////////////////////////
+// @brief PkThread structure for SBE Command Receiver thread
+////////////////////////////////////////////////////////////////
+PkThread g_sbeCommandReceiver_thread;
+
+////////////////////////////////////////////////////////////////
+// @brief PkThread structure for SBE Synchronous ChipOps
+// processing thread
+////////////////////////////////////////////////////////////////
+PkThread g_sbeSyncCommandProcessor_thread;
+
+////////////////////////////////////////////////////////////////
+//// @brief PkThread structure for SBE Asynchronous ChipOps
+//// processing thread
+////////////////////////////////////////////////////////////////
+PkThread g_sbeAsyncCommandProcessor_thread;
+
+
+////////////////////////////////////////////////////////////////
+// @brief sbeInitSems - Create the necessary semaphores
+//
+// @return PK_OK - Success
+// PK_INVALID_SEMAPHORE_AT_CREATE - Invalid PkSemaphore
+// PK_INVALID_ARGUMENT_SEMAPHORE - max_count is non-zero
+// and less than the initial_count
+////////////////////////////////////////////////////////////////
+uint32_t sbeInitSems(void)
+{
+ SBE_ENTER("sbeInitSems");
+ int l_rc = PK_OK;
+
+ do
+ {
+ l_rc = pk_semaphore_create(&g_sbeSemCmdRecv, 0, 1);
+ if (l_rc)
+ {
+ break;
+ }
+ l_rc = pk_semaphore_create(&g_sbeSemCmdProcess, 0, 1);
+ if (l_rc)
+ {
+ break;
+ }
+ l_rc = pk_semaphore_create(&g_sbeSemFifoReset, 0, 1);
+ if (l_rc)
+ {
+ break;
+ }
+ } while (false);
+
+ if (l_rc)
+ {
+ SBE_ERROR ("pk_semaphore_create, rc=[%d]", l_rc);
+ }
+ return l_rc;
+}
+
+////////////////////////////////////////////////////////////////
+// @brief createAndResumeThreadHelper
+// - Create and resume the given thread
+//
+// @param[in/out] io_thread A pointer to an PkThread structure to initialize
+// @param[in] i_thread_routine The subroutine that implements the thread
+// @param[in/out] io_arg Private data to be passed as the argument to the
+// thread routine when it begins execution
+// @param[in] i_stack The stack space of the thread
+// @param[in] i_stack_size The size of the stack in bytes
+// @param[in] i_priority The initial priority of the thread
+//
+// @return PK_OK Successfully created and resumed the thread
+//
+// @return PK_INVALID_THREAD_AT_CREATE io_thread is null
+// @return PK_INVALID_ARGUMENT_THREAD1 i_thread_routine is null
+// @return PK_INVALID_ARGUMENT_THREAD2 i_priority is invalid
+// @return PK_INVALID_ARGUMENT_THREAD3 the stack area wraps around
+// the end of memory.
+// @return PK_STACK_OVERFLOW The stack area at thread creation
+// is smaller than the min safe size
+// @return PK_INVALID_THREAD_AT_RESUME1 io_thread is null (unlikely)
+// @return PK_INVALID_THREAD_AT_RESUME2 The thread is not active,
+// i.e. has completed or been deleted,
+// @return PK_PRIORITY_IN_USE_AT_RESUME Another thread is already
+// mapped at the priority of the thread
+////////////////////////////////////////////////////////////////
+uint32_t createAndResumeThreadHelper(PkThread *io_pThread,
+ PkThreadRoutine i_thread_routine,
+ void *io_pArg,
+ PkAddress i_stack,
+ size_t i_stack_size,
+ sbeThreadPriorities i_priority)
+{
+ int l_rc = PK_OK;
+
+ // Thread creation
+ l_rc = pk_thread_create(io_pThread,
+ i_thread_routine,
+ io_pArg,
+ i_stack,
+ i_stack_size,
+ (PkThreadPriority)i_priority);
+ if(l_rc == PK_OK)
+ {
+ // resume the thread once created
+ l_rc = pk_thread_resume(io_pThread);
+ }
+
+ // Check for errors creating or resuming the thread
+ if(l_rc != PK_OK)
+ {
+ SBE_ERROR ("Failure creating/resuming thread, rc=[%d]", l_rc);
+ }
+
+ return l_rc;
+}
+
+////////////////////////////////////////////////////////////////
+// @brief sbeInitThreads
+// Create the resume all the firmware threads
+//
+// @return See createAndResumeThreadHelper for more details
+////////////////////////////////////////////////////////////////
+int sbeInitThreads(void)
+{
+ // Locals
+ uint32_t l_rc = PK_OK;
+
+ do
+ {
+ // Initialize Command receiver thread
+ l_rc = createAndResumeThreadHelper(&g_sbeCommandReceiver_thread,
+ sbeCommandReceiver_routine,
+ (void *)0,
+ (PkAddress)g_sbeCommandReceiver_stack,
+ SBE_THREAD_CMD_RECV_STACK_SIZE,
+ THREAD_PRIORITY_5);
+ if (l_rc)
+ {
+ break;
+ }
+
+ // Initialize Synchronous Command Processor thread
+ l_rc = createAndResumeThreadHelper(&g_sbeSyncCommandProcessor_thread,
+ sbeSyncCommandProcessor_routine,
+ (void *)0,
+ (PkAddress)g_sbeSyncCommandProcessor_stack,
+ SBE_THREAD_SYNC_CMD_PROC_STACK_SIZE,
+ THREAD_PRIORITY_7);
+ if (l_rc)
+ {
+ break;
+ }
+
+ // Initialize Asynchronous Command Processor thread
+ l_rc = createAndResumeThreadHelper(&g_sbeAsyncCommandProcessor_thread,
+ sbeAsyncCommandProcessor_routine,
+ (void *)0,
+ (PkAddress)g_sbeAsyncCommandProcessor_stack,
+ SBE_THREAD_ASYNC_CMD_PROC_STACK_SIZE,
+ THREAD_PRIORITY_6);
+ if (l_rc)
+ {
+ break;
+ }
+ } while (false);
+
+ // If there are any errors initializing the threads
+ if( l_rc )
+ {
+ SBE_ERROR ("Error Initializing a thread, rc=[%d]", l_rc);
+ }
+
+ return l_rc;
+}
+
+////////////////////////////////////////////////////////////////
+// @brief - main : SBE Application main
+////////////////////////////////////////////////////////////////
+uint32_t main(int argc, char **argv)
+{
+ SBE_TRACE("Enter SBE main");
+ int l_rc = 0;
+
+ // @TODO via RTC : 128818
+ // Explore on reclaiming the stack
+ // used by this Initialization code
+
+ do
+ {
+ // initializes kernel data -
+ // stack, threads, timebase, timers, etc.
+ l_rc = pk_initialize((PkAddress)g_sbe_Kernel_NCInt_stack,
+ SBE_NONCRITICAL_STACK_SIZE,
+ 0,
+ 500000000); // @TODO via RTC : 128819
+ // Need to obtain at Runtime, a new attribute?
+ if (l_rc)
+ {
+ break;
+ }
+
+ SBE_DEBUG("Completed PK init");
+
+ // Initialize the semaphores
+ l_rc = sbeInitSems();
+ if (l_rc)
+ {
+ break;
+ }
+
+ // Initialize SBE control loop threads
+ l_rc = sbeInitThreads();
+ if (l_rc)
+ {
+ break;
+ }
+
+ // Setup SBE PPE IRQs
+ l_rc = sbeIRQSetup();
+ if (l_rc)
+ {
+ break;
+ }
+
+ // Start running the highest priority thread.
+ // This function never returns
+ pk_start_threads();
+
+ } while (false);
+
+ return l_rc;
+}
diff --git a/sbe/sbefw/sbetrace.H b/sbe/sbefw/sbetrace.H
new file mode 100644
index 00000000..173f2c24
--- /dev/null
+++ b/sbe/sbefw/sbetrace.H
@@ -0,0 +1,35 @@
+#ifndef __SBEFW_SBE_TRACE_H
+#define __SBEFW_SBE_TRACE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "pk_api.h"
+#include "trac_interface.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#define SBE_ENTER_MRK ">>"
+#define SBE_EXIT_MRK "<<"
+#define SBE_ERR_MRK "E>"
+#define SBE_INF_MRK "I>"
+
+#define SBE_TRACE(args...) PK_TRACE(args)
+#define SBE_ENTER(args...) PK_TRACE(SBE_ENTER_MRK"" args)
+#define SBE_EXIT(args...) PK_TRACE(SBE_EXIT_MRK"" args)
+#define SBE_ERROR(args...) PK_TRACE(SBE_ERR_MRK"" args)
+#define SBE_INFO(args...) PK_TRACE(SBE_INF_MRK"" args)
+
+//Debug traces
+#define SBE_FW_DEBUG
+#ifdef SBE_FW_DEBUG
+#define SBE_DEBUG_MRK "D>"
+#define SBE_DEBUG(args...) PK_TRACE(SBE_DEBUG_MRK"" args)
+#else
+#define SBE_DEBUG(args...)
+#endif //SBE_FW_DEBUG
+
+#endif // __SBEFW_SBE_TRACE_H
diff --git a/sbe/sbefw/topfiles.mk b/sbe/sbefw/topfiles.mk
new file mode 100644
index 00000000..2a37526d
--- /dev/null
+++ b/sbe/sbefw/topfiles.mk
@@ -0,0 +1,5 @@
+TOP-CPP-SOURCES = sbemain.C sbeirq.C sbecmdreceiver.C sbecmdprocessor.C sbecmdparser.C sbecmdscomaccess.C sbecmdiplcontrol.C sbefifo.C
+TOP-C-SOURCES =
+TOP-S-SOURCES =
+
+TOP_OBJECTS = $(TOP-C-SOURCES:.c=.o) $(TOP-CPP-SOURCES:.C=.o) $(TOP-S-SOURCES:.S=.o)
OpenPOWER on IntegriCloud