diff options
author | Basabjit Sengupta <basengup@in.ibm.com> | 2015-03-23 23:34:22 -0500 |
---|---|---|
committer | Amit J. Tendolkar <amit.tendolkar@in.ibm.com> | 2015-06-19 12:18:45 -0500 |
commit | 6a51c182508d13c8072e5ad8868ae63d41f28d99 (patch) | |
tree | a1fd4a5e404283aad8d042d99ed5ec80ca67cb73 /sbe | |
parent | 5e9cb6846e5860c4f82d234760c32ca561ac3854 (diff) | |
download | talos-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/Makefile | 76 | ||||
-rw-r--r-- | sbe/sbefw/img_defs.mk | 244 | ||||
-rw-r--r-- | sbe/sbefw/link.cmd | 69 | ||||
-rw-r--r-- | sbe/sbefw/pk_app_cfg.h | 104 | ||||
-rw-r--r-- | sbe/sbefw/sbe_sp_intf.H | 198 | ||||
-rw-r--r-- | sbe/sbefw/sbecmdiplcontrol.C | 30 | ||||
-rw-r--r-- | sbe/sbefw/sbecmdiplcontrol.H | 26 | ||||
-rw-r--r-- | sbe/sbefw/sbecmdparser.C | 162 | ||||
-rw-r--r-- | sbe/sbefw/sbecmdparser.H | 92 | ||||
-rw-r--r-- | sbe/sbefw/sbecmdprocessor.C | 239 | ||||
-rw-r--r-- | sbe/sbefw/sbecmdreceiver.C | 160 | ||||
-rw-r--r-- | sbe/sbefw/sbecmdscomaccess.C | 282 | ||||
-rw-r--r-- | sbe/sbefw/sbecmdscomaccess.H | 35 | ||||
-rw-r--r-- | sbe/sbefw/sbeexeintf.H | 171 | ||||
-rw-r--r-- | sbe/sbefw/sbefifo.C | 250 | ||||
-rw-r--r-- | sbe/sbefw/sbefifo.H | 356 | ||||
-rw-r--r-- | sbe/sbefw/sbeirq.C | 104 | ||||
-rw-r--r-- | sbe/sbefw/sbeirq.H | 84 | ||||
-rw-r--r-- | sbe/sbefw/sbemain.C | 265 | ||||
-rw-r--r-- | sbe/sbefw/sbetrace.H | 35 | ||||
-rw-r--r-- | sbe/sbefw/topfiles.mk | 5 |
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) |