diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/build/img_defs.mk | 5 | ||||
-rw-r--r-- | src/build/power_defs.mk | 2 | ||||
-rw-r--r-- | src/sbefw/app/power/chipop_table.C | 1 | ||||
-rw-r--r-- | src/sbefw/app/power/sbecmdmpipl.C | 243 | ||||
-rw-r--r-- | src/sbefw/app/power/sbecmdmpipl.H | 27 | ||||
-rw-r--r-- | src/sbefw/core/corefiles.mk | 6 | ||||
-rw-r--r-- | src/sbefw/core/sbe_sp_intf.H | 3 | ||||
-rw-r--r-- | src/sbefw/core/sbecmdprocessor.C | 24 | ||||
-rw-r--r-- | src/sbefw/core/sbecmdreceiver.C | 22 | ||||
-rw-r--r-- | src/sbefw/core/sbeexeintf.H | 9 | ||||
-rw-r--r-- | src/sbefw/core/sbeirq.C | 77 | ||||
-rw-r--r-- | src/sbefw/core/sbes0handler.C | 144 | ||||
-rw-r--r-- | src/sbefw/core/sbes0handler.H | 56 |
13 files changed, 490 insertions, 129 deletions
diff --git a/src/build/img_defs.mk b/src/build/img_defs.mk index 02839183..c6cd7d8d 100644 --- a/src/build/img_defs.mk +++ b/src/build/img_defs.mk @@ -467,6 +467,11 @@ endif ifeq ($(img), pibmem) GCC-DEFS += -DPIBMEM_ONLY_IMAGE endif + +ifeq ($(SBE_S0_SUPPORT), 1) +GCC-DEFS += -D_S0_=$(SBE_S0_SUPPORT) +endif + ############################################################################ CFLAGS = PPE-CFLAGS = $(CFLAGS) -c $(GCC-CFLAGS) $(PIPE-CFLAGS) $(GCC-O-LEVEL) $(INCLUDES) diff --git a/src/build/power_defs.mk b/src/build/power_defs.mk index ca676b80..d9db8b07 100644 --- a/src/build/power_defs.mk +++ b/src/build/power_defs.mk @@ -34,6 +34,8 @@ FAPI_TRACE_LEVEL_DEF = 2 HOST_INTERFACE_AVAILABLE = 1 +export SBE_S0_SUPPORT = 1 + ISTEP2_INFRA_DIR = $(IMPORT_HWP_MK_DIR)/istep2 ISTEP3_INFRA_DIR = $(IMPORT_HWP_MK_DIR)/istep3 ISTEP4_INFRA_DIR = $(IMPORT_HWP_MK_DIR)/istep4 diff --git a/src/sbefw/app/power/chipop_table.C b/src/sbefw/app/power/chipop_table.C index 4ba84581..fb0f6ea1 100644 --- a/src/sbefw/app/power/chipop_table.C +++ b/src/sbefw/app/power/chipop_table.C @@ -42,7 +42,6 @@ #include "sbecmdtracearray.H" #include "sbecmdCntrlTimer.H" #include "sbecmdfastarray.H" - #include "core/chipop_handler.H" #include "app/common/sbecmdgeneric.H" diff --git a/src/sbefw/app/power/sbecmdmpipl.C b/src/sbefw/app/power/sbecmdmpipl.C index 47e76bcd..b12453eb 100644 --- a/src/sbefw/app/power/sbecmdmpipl.C +++ b/src/sbefw/app/power/sbecmdmpipl.C @@ -81,6 +81,71 @@ static const uint32_t ISTEP_MINOR_START = 1; static const uint32_t ISTEP4_MAX_SUBSTEPS = 34; static const uint32_t ISTEP5_MAX_SUBSTEPS = 2; +ReturnCode startMpiplIstepsExecute(void) +{ + #define SBE_FUNC " startMpiplIstepsExecute " + SBE_ENTER(SBE_FUNC); + ReturnCode fapiRc = FAPI2_RC_SUCCESS; + + uint32_t minor = 1; + do + { + fapiRc = sbeExecuteIstep(SBE_ISTEP_MPIPL_START, minor); + if(fapiRc != FAPI2_RC_SUCCESS) + { + SBE_ERROR(SBE_FUNC "Failed in StartMpipl Minor Isteps[%d]", minor); + break; + } + ++minor; + }while(minor<=MPIPL_START_MAX_SUBSTEPS); + + SBE_EXIT(SBE_FUNC); + return fapiRc; + #undef SBE_FUNC +} + +static const uint8_t g_continuempipl_isteps[3][3] = { + // Major Num, Minor Start, Minor End + {SBE_ISTEP_MPIPL_CONTINUE, ISTEP_MINOR_START, MPIPL_CONTINUE_MAX_SUBSTEPS}, + {SBE_ISTEP4, ISTEP_MINOR_START, ISTEP4_MAX_SUBSTEPS}, + {SBE_ISTEP5, ISTEP_MINOR_START, ISTEP5_MAX_SUBSTEPS}}; + + +ReturnCode continueMpiplIstepsExecute(const sbeRole i_sbeRole) +{ + #define SBE_FUNC " continueMpiplIstepsExecute " + SBE_ENTER(SBE_FUNC); + ReturnCode fapiRc = FAPI2_RC_SUCCESS; + + // Loop through isteps + for( auto istep : g_continuempipl_isteps ) + { + for(uint8_t minor = istep[1]; minor <= istep[2]; minor++) + { + fapiRc = sbeExecuteIstep(istep[0], minor); + if(fapiRc != FAPI2_RC_SUCCESS) + { + SBE_ERROR(SBE_FUNC "Failed in Master ContinueMpipl Isteps " + "Major[%d] Minor[%d]", istep[0], minor); + break; + } + } + if(fapiRc != FAPI2_RC_SUCCESS) + { + break; + } + if(i_sbeRole == SBE_ROLE_SLAVE) + { + (void)SbeRegAccess::theSbeRegAccess().stateTransition( + SBE_RUNTIME_EVENT); + break; + } + } + SBE_EXIT(SBE_FUNC); + return fapiRc; + #undef SBE_FUNC +} + /////////////////////////////////////////////////////////////////////// // @brief sbeEnterMpipl Sbe enter MPIPL function // @@ -90,49 +155,42 @@ uint32_t sbeEnterMpipl(uint8_t *i_pArg) { #define SBE_FUNC " sbeEnterMpipl " SBE_ENTER(SBE_FUNC); - uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL; - uint32_t l_fapiRc = FAPI2_RC_SUCCESS; + uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL; + ReturnCode fapiRc = FAPI2_RC_SUCCESS; uint32_t len = 0; - sbeRespGenHdr_t l_respHdr; - l_respHdr.init(); - sbeResponseFfdc_t l_ffdc; + + sbeResponseFfdc_t ffdc; + sbeRespGenHdr_t respHdr; + respHdr.init(); do { // Dequeue the EOT entry as no more data is expected. - l_rc = sbeUpFifoDeq_mult (len, NULL); - CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc); + rc = sbeUpFifoDeq_mult (len, NULL); + CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(rc); - uint32_t l_minor = 1; - do + fapiRc = startMpiplIstepsExecute(); + bool checkstop = isSystemCheckstop(); + if((fapiRc != FAPI2_RC_SUCCESS) || checkstop) { - l_fapiRc = sbeExecuteIstep(SBE_ISTEP_MPIPL_START, l_minor); - bool checkstop = isSystemCheckstop(); - if((l_fapiRc != FAPI2_RC_SUCCESS) || checkstop) + SBE_ERROR(SBE_FUNC "Failed in Mpipl Start in ChipOp Mode"); + if(checkstop) { - SBE_ERROR(SBE_FUNC "Failed in Mpipl Start in ChipOp Mode " - "Minor: %d", l_minor); - if(checkstop) - { - l_respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE, - SBE_SEC_SYSTEM_CHECKSTOP); - } - else - { - l_respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE, - SBE_SEC_GENERIC_FAILURE_IN_EXECUTION); - l_ffdc.setRc(l_fapiRc); - } - // reset attribute. We do not want to reset register, so do not - // use setMpIplMode - uint8_t isMpipl = 0; - PLAT_ATTR_INIT(ATTR_IS_MPIPL, Target<TARGET_TYPE_SYSTEM>(), - isMpipl); - break; + respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE, + SBE_SEC_SYSTEM_CHECKSTOP); } - ++l_minor; - }while(l_minor<=MPIPL_START_MAX_SUBSTEPS); - + else + { + respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE, + SBE_SEC_GENERIC_FAILURE_IN_EXECUTION); + ffdc.setRc(fapiRc); + } + // reset attribute. We do not want to reset register, so do not + // use setMpIplMode + uint8_t isMpipl = 0; + PLAT_ATTR_INIT(ATTR_IS_MPIPL, Target<TARGET_TYPE_SYSTEM>(), isMpipl); + break; + } }while(0); // Create the Response to caller @@ -140,12 +198,12 @@ uint32_t sbeEnterMpipl(uint8_t *i_pArg) { // If there was a FIFO error, will skip sending the response, // instead give the control back to the command processor thread - CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc); - l_rc = sbeDsSendRespHdr( l_respHdr, &l_ffdc); + CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(rc); + rc = sbeDsSendRespHdr( respHdr, &ffdc); }while(0); SBE_EXIT(SBE_FUNC); - return l_rc; + return rc; #undef SBE_FUNC } @@ -158,66 +216,42 @@ uint32_t sbeContinueMpipl(uint8_t *i_pArg) { #define SBE_FUNC " sbeContinueMpipl " SBE_ENTER(SBE_FUNC); - uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL; + uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL; + ReturnCode fapiRc = FAPI2_RC_SUCCESS; uint32_t len = 0; - ReturnCode l_fapiRc = FAPI2_RC_SUCCESS; - sbeResponseFfdc_t l_ffdc; - sbeRespGenHdr_t l_respHdr; - l_respHdr.init(); + sbeResponseFfdc_t ffdc; + sbeRespGenHdr_t respHdr; + respHdr.init(); do { // Dequeue the EOT entry as no more data is expected. - l_rc = sbeUpFifoDeq_mult (len, NULL); - CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc); + rc = sbeUpFifoDeq_mult (len, NULL); + CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(rc); - sbeRole l_sbeRole = SbeRegAccess::theSbeRegAccess().isSbeSlave() ? + sbeRole sbeRole = SbeRegAccess::theSbeRegAccess().isSbeSlave() ? SBE_ROLE_SLAVE : SBE_ROLE_MASTER; - // Run isteps - const uint8_t isteps[][3] = { - // Major Num, Minor Start, Minor End - {SBE_ISTEP_MPIPL_CONTINUE, ISTEP_MINOR_START, MPIPL_CONTINUE_MAX_SUBSTEPS}, - {SBE_ISTEP4, ISTEP_MINOR_START, ISTEP4_MAX_SUBSTEPS}, - {SBE_ISTEP5, ISTEP_MINOR_START, ISTEP5_MAX_SUBSTEPS}}; - // Loop through isteps - for( auto istep : isteps) + fapiRc = continueMpiplIstepsExecute(sbeRole); + bool checkstop = isSystemCheckstop(); + if((fapiRc != FAPI2_RC_SUCCESS) || checkstop) { - // This is required here to skip the major istep 4/5 in slave - if((SBE_ROLE_SLAVE == l_sbeRole) && - (istep[0] == 4 || istep[0] == 5)) + SBE_ERROR(SBE_FUNC "Failed in Continue Mpipl in ChipOp Mode, " + "SBE Role[%d]", sbeRole); + if(checkstop) { - (void)SbeRegAccess::theSbeRegAccess().stateTransition( - SBE_RUNTIME_EVENT); - continue; + respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE, + SBE_SEC_SYSTEM_CHECKSTOP); } - for(uint8_t l_minor = istep[1]; l_minor <= istep[2]; l_minor++) - { - l_fapiRc = sbeExecuteIstep(istep[0], l_minor); - bool checkstop = isSystemCheckstop(); - if((l_fapiRc != FAPI2_RC_SUCCESS) || checkstop) - { - SBE_ERROR(SBE_FUNC "Failed in Mpipl continue in ChipOp " - "Mode Major [%d] Minor [%d]", istep[0], l_minor); - if(checkstop) - { - l_respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE, - SBE_SEC_SYSTEM_CHECKSTOP); - } - else - { - l_respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE, - SBE_SEC_GENERIC_FAILURE_IN_EXECUTION); - l_ffdc.setRc(l_fapiRc); - } - break; - } - } - if(l_ffdc.getRc() != FAPI2_RC_SUCCESS) + else { - break; + respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE, + SBE_SEC_GENERIC_FAILURE_IN_EXECUTION); + ffdc.setRc(fapiRc); + // Async Response to be stored } + break; } }while(0); @@ -228,15 +262,52 @@ uint32_t sbeContinueMpipl(uint8_t *i_pArg) // Create the Response to caller // If there was a FIFO error, will skip sending the response, // instead give the control back to the command processor thread - if(SBE_SEC_OPERATION_SUCCESSFUL == l_rc) + if(SBE_SEC_OPERATION_SUCCESSFUL == rc) { - l_rc = sbeDsSendRespHdr( l_respHdr, &l_ffdc); + rc = sbeDsSendRespHdr( respHdr, &ffdc); } SBE_EXIT(SBE_FUNC); - return l_rc; + return rc; #undef SBE_FUNC } +#ifdef _S0_ +/////////////////////////////////////////////////////////////////////// +// @brief stopClockS0 Sbe StopClock S0 interface function +// +// @return RC from the underlying FIFO utility +/////////////////////////////////////////////////////////////////////// +ReturnCode stopClockS0() +{ +#define SBE_FUNC "stopClockS0" + SBE_ENTER(SBE_FUNC); + uint32_t fapiRc = FAPI2_RC_SUCCESS; + p9_stopclocks_flags flags; + + p9hcd::P9_HCD_CLK_CTRL_CONSTANTS clk_regions = + p9hcd::CLK_REGION_ALL_BUT_PLL_REFR; + p9hcd::P9_HCD_EX_CTRL_CONSTANTS ex_select = p9hcd::BOTH_EX; + + flags.clearAll(); + flags.sync_stop_quad_clks = false; + flags.stop_core_clks = true; + flags.stop_cache_clks = true; + + SBE_EXEC_HWP(fapiRc, p9_stopclocks_hwp, + plat_getChipTarget(), + flags, + clk_regions, + ex_select); + if(fapiRc != FAPI2_RC_SUCCESS) + { + SBE_ERROR(SBE_FUNC "Failed in StopClock S0S1 Interface"); + } + + SBE_EXIT(SBE_FUNC); + return fapiRc; +#undef SBE_FUNC +} +#endif /////////////////////////////////////////////////////////////////////// /* @brief Deduce the type of stop clock procedure to call based on * target and chiplet id combination diff --git a/src/sbefw/app/power/sbecmdmpipl.H b/src/sbefw/app/power/sbecmdmpipl.H index 34582b48..adda51eb 100644 --- a/src/sbefw/app/power/sbecmdmpipl.H +++ b/src/sbefw/app/power/sbecmdmpipl.H @@ -6,6 +6,7 @@ /* OpenPOWER sbe Project */ /* */ /* Contributors Listed Below - COPYRIGHT 2016,2018 */ +/* [+] International Business Machines Corp. */ /* */ /* */ /* Licensed under the Apache License, Version 2.0 (the "License"); */ @@ -32,6 +33,7 @@ #define __SBEFW_SBECMDMPIPL_H #include <stdint.h> +#include "sbestates.H" /** * @brief Handles Sbe Enter Mpipl chip-op (0xA901) @@ -60,4 +62,29 @@ uint32_t sbeContinueMpipl(uint8_t *i_pArg); */ uint32_t sbeStopClocks(uint8_t *i_pArg); +/** + * @brief Handles Sbe Start MPIPL iSteps + * + * @return Rc from the FIFO access utility + */ +fapi2::ReturnCode startMpiplIstepsExecute(void); + +/** + * @brief Handles Sbe Continue MPIPL iSteps based on Master/Slave SBE + * + * @param[in] i_sbeRole Master/Slave SBE + * + * @return Rc from the FIFO access utility + */ +fapi2::ReturnCode continueMpiplIstepsExecute(const sbeRole i_sbeRole); + +#ifdef _S0_ +/** + * @brief Handles Sbe Stop Clock (Core/Cache) procedure in S0 context + * + * @return Rc from the FIFO access utility + */ +fapi2::ReturnCode stopClockS0(); +#endif + #endif /* __SBEFW_SBECMDMPIPL_H */ diff --git a/src/sbefw/core/corefiles.mk b/src/sbefw/core/corefiles.mk index 4ab1450c..3b3bf233 100644 --- a/src/sbefw/core/corefiles.mk +++ b/src/sbefw/core/corefiles.mk @@ -44,6 +44,9 @@ COREPIBMEM-CPP-SOURCES += sbeSecureMemRegionManager.C COREPIBMEM-CPP-SOURCES += sbeSecurity.C COREPIBMEM-CPP-SOURCES += chipop_handler.C COREPIBMEM-CPP-SOURCES += ipl.C +ifeq ($(SBE_S0_SUPPORT), 1) +COREPIBMEM-CPP-SOURCES += sbes0handler.C +endif COREPIBMEM-C-SOURCES = COREPIBMEM-S-SOURCES = @@ -52,6 +55,9 @@ COREPIBMEM_OBJECTS = $(COREPIBMEM-C-SOURCES:.c=.o) $(COREPIBMEM-CPP-SOURCES:.C=. # seeprom objects CORESEEPROM-CPP-SOURCES = sbeSecureMemRegionManager.C +ifeq ($(SBE_S0_SUPPORT), 1) +CORESEEPROM-CPP-SOURCES += sbes0handler.C +endif CORESEEPROM-C-SOURCES = CORESEEPROM-S-SOURCES = diff --git a/src/sbefw/core/sbe_sp_intf.H b/src/sbefw/core/sbe_sp_intf.H index ae4876e9..e35ac4be 100644 --- a/src/sbefw/core/sbe_sp_intf.H +++ b/src/sbefw/core/sbe_sp_intf.H @@ -222,6 +222,9 @@ enum sbeSecondaryResponse SBE_SEC_DMT_TIMEOUT = 0x21, SBE_SEC_SYSTEM_CHECKSTOP = 0x22, SBE_SEC_BLACKLISTED_REG_ACCESS_BLOCKED = 0x23, + SBE_SEC_S0_START_MPIPL_FAILED = 0x24, + SBE_SEC_S0_STOP_CLOCK_FAILED = 0x25, + SBE_SEC_S0_CONTINUE_MPIPL_FAILED = 0x26, }; /** diff --git a/src/sbefw/core/sbecmdprocessor.C b/src/sbefw/core/sbecmdprocessor.C index 1c1f2698..a70bb4eb 100644 --- a/src/sbefw/core/sbecmdprocessor.C +++ b/src/sbefw/core/sbecmdprocessor.C @@ -48,6 +48,11 @@ #include "sbeglobals.H" #include "core/chipop_handler.H" #include "core/ipl.H" + +#ifdef _S0_ +#include "sbes0handler.H" +#endif + using namespace fapi2; // Forward declaration for performAttrSetup @@ -325,6 +330,16 @@ void sbeSyncCommandProcessor_routine(void *i_pArg) SBE_GLOBAL->sbeIntrSource.setIntrSource(SBE_PROC_ROUTINE, SBE_INTERFACE_FIFO); } +#ifdef _S0_ + else if ( SBE_GLOBAL->sbeIntrSource.isSet(SBE_RX_ROUTINE, + SBE_INTERFACE_S0) ) + { + SBE_GLOBAL->sbeIntrSource.setIntrSource(SBE_PROC_ROUTINE, + SBE_INTERFACE_S0); + l_rc = sbeHandleS0((uint8_t *)i_pArg); + break; + } +#endif else // SBE_INTERFACE_FIFO_RESET or SBE_INTERFACE_UNKNOWN { SBE_ERROR(SBE_FUNC"Unexpected interrupt communicated to the " @@ -380,6 +395,15 @@ void sbeSyncCommandProcessor_routine(void *i_pArg) pk_irq_enable(SBE_IRQ_SBEFIFO_DATA); pk_irq_enable(SBE_IRQ_SBEFIFO_RESET); } +#ifdef _S0_ + else if ( SBE_GLOBAL->sbeIntrSource.isSet(SBE_PROC_ROUTINE, SBE_INTERFACE_S0) ) + { + // No Response to handle here, Async response + // Enable Host interrupt + SBE_GLOBAL->sbeIntrSource.clearIntrSource(SBE_ALL_HANDLER,SBE_INTERFACE_S0); + pk_irq_enable(SBE_IRQ_INTR0); + } +#endif } while(true); // Thread always exists SBE_EXIT(SBE_FUNC); } diff --git a/src/sbefw/core/sbecmdreceiver.C b/src/sbefw/core/sbecmdreceiver.C index 15017a47..6ed11c37 100644 --- a/src/sbefw/core/sbecmdreceiver.C +++ b/src/sbefw/core/sbecmdreceiver.C @@ -43,6 +43,10 @@ #include "sbeutil.H" #include "sbeglobals.H" +#ifdef _S0_ +#include "sbes0handler.H" +#endif + #include "core/chipop_handler.H" ////////////////////////////////////////////////////// @@ -61,7 +65,8 @@ void sbeCommandReceiver_routine(void *i_pArg) { // @TODO via RTC: 128944 // Read Scratchpad - // Wait for new data in FIFO or FIFO reset interrupt or PSU interrupt + // Wait for new data in FIFO or FIFO reset interrupt or PSU interrupt or + // s0/s1 interrupt int l_rcPk = pk_semaphore_pend (&SBE_GLOBAL->sbeSemCmdRecv, PK_WAIT_FOREVER); do @@ -171,6 +176,21 @@ void sbeCommandReceiver_routine(void *i_pArg) l_command = SBE_GLOBAL->sbeFifoCmdHdr.command; } // end else if loop for FIFO interface chipOp handling +#ifdef _S0_ + // Received S0 interrupt + else if ( SBE_GLOBAL->sbeIntrSource.isSet(SBE_INTERRUPT_ROUTINE, + SBE_INTERFACE_S0) ) + { + //Clear interrupt source bit PERV_SB_CS_SCOM + clearS0interrupt(); + //Clear the Interrupt Source bit for S0 + SBE_GLOBAL->sbeIntrSource.clearIntrSource(SBE_INTERRUPT_ROUTINE, + SBE_INTERFACE_S0); + curInterface = SBE_INTERFACE_S0; + // Break out from Command/Class validation, post to processor + break; + } +#endif // Any other FIFO access issue if ( l_rc != SBE_SEC_OPERATION_SUCCESSFUL) { diff --git a/src/sbefw/core/sbeexeintf.H b/src/sbefw/core/sbeexeintf.H index eaeab51c..dc4f6936 100644 --- a/src/sbefw/core/sbeexeintf.H +++ b/src/sbefw/core/sbeexeintf.H @@ -87,10 +87,13 @@ enum sbeThreadStackSize */ typedef enum { - SBE_INTERFACE_UNKNOWN = 0x00, - SBE_INTERFACE_FIFO = 0x01, - SBE_INTERFACE_PSU = 0x02, + SBE_INTERFACE_UNKNOWN = 0x00, + SBE_INTERFACE_FIFO = 0x01, + SBE_INTERFACE_PSU = 0x02, SBE_INTERFACE_FIFO_RESET = 0x04, +#ifdef _S0_ + SBE_INTERFACE_S0 = 0x08, +#endif } sbeInterfaceSrc_t; /* diff --git a/src/sbefw/core/sbeirq.C b/src/sbefw/core/sbeirq.C index a1d5b72b..c99c459a 100644 --- a/src/sbefw/core/sbeirq.C +++ b/src/sbefw/core/sbeirq.C @@ -43,6 +43,8 @@ // - FIFO new data available // - FIFO reset request // - PSU new data available +// - S0 Interrupt +// - S1 Interrupt // // @param[in] i_pArg - Unused // @param[in] i_irq - IRQ number as defined in sbeirq.h @@ -73,7 +75,12 @@ void sbe_interrupt_handler (void *i_pArg, PkIrqId i_irq) SBE_INTERFACE_FIFO_RESET); pk_irq_disable(SBE_IRQ_SBEFIFO_DATA); break; - +#ifdef _S0_ + case SBE_IRQ_INTR0: + SBE_GLOBAL->sbeIntrSource.setIntrSource(SBE_INTERRUPT_ROUTINE, + SBE_INTERFACE_S0); + break; +#endif default: SBE_ERROR(SBE_FUNC"Unknown IRQ, assert"); assert(0); @@ -95,61 +102,55 @@ void sbe_interrupt_handler (void *i_pArg, PkIrqId i_irq) #undef SBE_FUNC } +// Interrupts which are available in SBE, in an array +static uint32_t G_supported_irqs[] = { + SBE_IRQ_HOST_PSU_INTR, + SBE_IRQ_SBEFIFO_DATA, + SBE_IRQ_SBEFIFO_RESET, +#ifdef _S0_ + SBE_IRQ_INTR0, +#endif + }; + +// Create the Vector mask for all the interrupts in SBE, +// required to call disable/enable with this vector mask +constexpr uint64_t getVectorMask ( size_t index ) +{ + return (index >= (sizeof(G_supported_irqs)/sizeof(uint32_t))? + 0:STD_IRQ_MASK64(G_supported_irqs[index])|getVectorMask(index + 1)); +} + //////////////////////////////////////////////////////////////// // See sbeexeintf.h for more details //////////////////////////////////////////////////////////////// int sbeIRQSetup (void) { #define SBE_FUNC " sbeIRQSetup " - int l_rc = 0; - PkIrqId l_irq; + int rc = 0; + uint64_t vector_mask = getVectorMask(0); // Disable the relevant IRQs while we set them up - pk_irq_disable(SBE_IRQ_HOST_PSU_INTR); - pk_irq_disable(SBE_IRQ_SBEFIFO_DATA); - pk_irq_disable(SBE_IRQ_SBEFIFO_RESET); + pk_irq_vec_disable(vector_mask); - do + for(uint32_t cnt=0; cnt<sizeof(G_supported_irqs)/sizeof(uint32_t); cnt++) { // Register the IRQ handler with PK - - // PSU New data available interrupt - l_irq = SBE_IRQ_HOST_PSU_INTR; - l_rc = pk_irq_handler_set(l_irq, sbe_interrupt_handler, NULL); - if(l_rc) + rc = pk_irq_handler_set(G_supported_irqs[cnt], sbe_interrupt_handler, NULL); + if(rc) { + SBE_ERROR (SBE_FUNC "pk_irq_handler_set failed, IRQ=[0x%02X], " + "rc=[%d]", G_supported_irqs[cnt], rc); break; } + } - // FIFO New data available interrupt - l_irq = SBE_IRQ_SBEFIFO_DATA; - l_rc = pk_irq_handler_set(l_irq, sbe_interrupt_handler, NULL); - if(l_rc) - { - break; - } - - // FIFO Reset request - l_irq = SBE_IRQ_SBEFIFO_RESET; - l_rc = pk_irq_handler_set(l_irq, sbe_interrupt_handler, NULL); - if(l_rc) - { - break; - } - - // Enable the IRQ - pk_irq_enable(SBE_IRQ_SBEFIFO_RESET); - pk_irq_enable(SBE_IRQ_SBEFIFO_DATA); - pk_irq_enable(SBE_IRQ_HOST_PSU_INTR); - } while(false); - - if (l_rc) + if(!rc) { - SBE_ERROR (SBE_FUNC"pk_irq_handler_set failed, IRQ=[0x%02X], " - "rc=[%d]", l_irq, l_rc); + // Enable the IRQ + pk_irq_vec_enable(vector_mask); } - return l_rc; + return rc; #undef SBE_FUNC } diff --git a/src/sbefw/core/sbes0handler.C b/src/sbefw/core/sbes0handler.C new file mode 100644 index 00000000..dd16e777 --- /dev/null +++ b/src/sbefw/core/sbes0handler.C @@ -0,0 +1,144 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/sbefw/core/sbes0handler.C $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2017,2018 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/* + * @file: ppe/src/sbefw/sbes0handler.C + * + * @brief This file contains the SBE S0 Handler + * + */ + +#include "sbefifo.H" +#include "sbeSpMsg.H" +#include "sbe_sp_intf.H" +#include "sbetrace.H" +#include "sbeFifoMsgUtils.H" +#include "sberegaccess.H" +#include "sbefapiutil.H" +#include "sbecmdiplcontrol.H" +#include "sbecmdmpipl.H" +#include "sbeFFDC.H" +#include "sbes0handler.H" + +#include "fapi2.H" +#include "p9_perv_scom_addresses.H" + +using namespace fapi2; + +#ifdef __SBEFW_SEEPROM__ + +/////////////////////////////////////////////////////////////////////// +// @brief sbeHandleS0 +// +// @return RC from the function +/////////////////////////////////////////////////////////////////////// +uint32_t sbeHandleS0(uint8_t *i_pArg) +{ + #define SBE_FUNC " sbeHandleS0 " + SBE_ENTER(SBE_FUNC); + uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL; + ReturnCode fapiRc = FAPI2_RC_SUCCESS; + + do // Do while for both StartMpipl and ContinueMpipl + { + fapiRc = startMpiplIstepsExecute(); + if(fapiRc != FAPI2_RC_SUCCESS) + { + rc = SBE_SEC_S0_START_MPIPL_FAILED; + SBE_ERROR(SBE_FUNC "Failed in Start Mpipl S0 Interface"); + break; + } + + // TODO - RTC: 190585 + //Core and Cache stop Clock + fapiRc = stopClockS0(); + if(fapiRc != FAPI2_RC_SUCCESS) + { + rc = SBE_SEC_S0_STOP_CLOCK_FAILED; + SBE_ERROR(SBE_FUNC "Failed in Core/Cache StopClock S0 Interface"); + break; + } + + sbeRole sbeRole = SbeRegAccess::theSbeRegAccess().isSbeSlave() ? + SBE_ROLE_SLAVE : SBE_ROLE_MASTER; + + if(sbeRole == SBE_ROLE_MASTER) + { + fapiRc = continueMpiplIstepsExecute(sbeRole); + if(fapiRc != FAPI2_RC_SUCCESS) + { + rc = SBE_SEC_S0_CONTINUE_MPIPL_FAILED; + SBE_ERROR(SBE_FUNC "Failed in Continue Mpipl S0 Interface, " + "SBE Role[%d]", sbeRole); + break; + } + } + }while(0); + + if(rc) + { + // Async Response to be stored + captureAsyncFFDC(SBE_PRI_GENERIC_EXECUTION_FAILURE, rc); + } + SBE_EXIT(SBE_FUNC); + return rc; + #undef SBE_FUNC +} + +#endif // #ifdef __SBEFW_SEEPROM__ + +#ifndef __SBEFW_SEEPROM__ + +uint32_t clearS0interrupt() +{ + #define SBE_FUNC "clearS0interrupt" + SBE_ENTER(SBE_FUNC); + uint32_t rc = FAPI2_RC_SUCCESS; + // Default Mask bit for S0 Innterrupt, bit 49 + uint64_t MASK_ALL_AND_MODIFY_BIT = 0xFFFDFFFFFFFFFFFFULL; + + do + { + Target<TARGET_TYPE_PROC_CHIP > procTgt = plat_getChipTarget(); + uint64_t data; + rc = getscom_abs_wrap (&procTgt, PERV_SB_CS_SCOM, &data); + if( rc ) + { + break; + } + data = data & MASK_ALL_AND_MODIFY_BIT; + rc = putscom_abs_wrap (&procTgt, PERV_SB_CS_SCOM, data); + if( rc ) + { + break; + } + }while(0); + + SBE_EXIT(SBE_FUNC); + return rc; + #undef SBE_FUNC +} + +#endif // #ifndef __SBEFW_SEEPROM__ + diff --git a/src/sbefw/core/sbes0handler.H b/src/sbefw/core/sbes0handler.H new file mode 100644 index 00000000..35aa9d12 --- /dev/null +++ b/src/sbefw/core/sbes0handler.H @@ -0,0 +1,56 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/sbefw/core/sbes0handler.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2017,2018 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/* + * @file: ppe/src/sbefw/sbes0handler.H + * + * @brief This file contains the Interfaces for S0 Handlers + * + */ + +#ifndef __SBEFW_SBES0HANDLER_H +#define __SBEFW_SBES0HANDLER_H + +#include <stdint.h> +#include <sbeexeintf.H> + +/** + * @brief Handles Sbe S0 Interrupt + * + * @param[in] i_pArg Buffer to be passed to the function (not used as of now) + * + * @return Rc from the function + */ +uint32_t sbeHandleS0(uint8_t *i_pArg); + +/** + * @brief Clear S0 interrupt source bit in PERV_SB_CS_SCOM + * + * @param[in] i_pArg Interrupt bit to identify S0 + * + * @return Rc from the function + */ +uint32_t clearS0interrupt(); + +#endif /* __SBEFW_SBES0HANDLER_H */ |