summaryrefslogtreecommitdiffstats
path: root/src/sbefw
diff options
context:
space:
mode:
Diffstat (limited to 'src/sbefw')
-rw-r--r--src/sbefw/sbeHostUtils.H5
-rw-r--r--src/sbefw/sbeSpMsg.H11
-rw-r--r--src/sbefw/sbe_sp_intf.H1
-rw-r--r--src/sbefw/sbecmdmemaccess.C41
4 files changed, 57 insertions, 1 deletions
diff --git a/src/sbefw/sbeHostUtils.H b/src/sbefw/sbeHostUtils.H
index 092c884b..33fc9db8 100644
--- a/src/sbefw/sbeHostUtils.H
+++ b/src/sbefw/sbeHostUtils.H
@@ -93,6 +93,11 @@ typedef enum
// This would be used to trigger hostboot in istep 16
SBE_SBE2PSU_DOORBELL_SET_BIT2 = 0x2000000000000000ull,
+ // Bit 4 OR flag for SBE->PSU Doorbell Register,
+ // When this is set by SBE, it would trigger an interrupt to host
+ // firmware to inform that Host Pass through command received.
+ SBE_SBE2PSU_DOORBELL_SET_BIT4 = 0x0800000000000000ull,
+
// Bit 14 OR flag for SBE->PSU Doorbell Register;
// When this is set by SBE, it would trigger an interrupt to host
// firmware to inform that timer has expired.
diff --git a/src/sbefw/sbeSpMsg.H b/src/sbefw/sbeSpMsg.H
index 65308ff1..c24c5e1c 100644
--- a/src/sbefw/sbeSpMsg.H
+++ b/src/sbefw/sbeSpMsg.H
@@ -428,6 +428,17 @@ typedef struct
return l_len;
}
+ /**
+ * @brief Determines if it is Host Pass-through Command
+ *
+ * @return Returns True if Host Pass-through mode is set
+ * False if Host Pass-through mode is not set
+ */
+ uint32_t isPbaHostPassThroughModeSet() const
+ {
+ return ((flags & SBE_MEM_ACCESS_FLAGS_HOST_PASS_THROUGH) ? true : false);
+ }
+
}sbeMemAccessReqMsgHdr_t;
/**
diff --git a/src/sbefw/sbe_sp_intf.H b/src/sbefw/sbe_sp_intf.H
index fdc49770..45dfafdc 100644
--- a/src/sbefw/sbe_sp_intf.H
+++ b/src/sbefw/sbe_sp_intf.H
@@ -293,6 +293,7 @@ enum sbeMemoryAccessFlags
SBE_MEM_ACCESS_FLAGS_FAST_MODE_ON = 0x0020,
SBE_MEM_ACCESS_FLAGS_LCO_ENABLED = 0x0040, //required only in PBA-PUT
SBE_MEM_ACCESS_FLAGS_CACHE_INHIBIT = 0x0080, //required in I/O oper ADU
+ SBE_MEM_ACCESS_FLAGS_HOST_PASS_THROUGH = 0x0100, // Host pass through mode (PBA)
SBE_MEM_ACCESS_FLAGS_INJECT_ON = 0x0200, // Inject mode ( PBA put )
};
diff --git a/src/sbefw/sbecmdmemaccess.C b/src/sbefw/sbecmdmemaccess.C
index aa582e45..93126d49 100644
--- a/src/sbefw/sbecmdmemaccess.C
+++ b/src/sbefw/sbecmdmemaccess.C
@@ -35,6 +35,8 @@
#include "sbetrace.H"
#include "sbeFifoMsgUtils.H"
#include "sbeutil.H"
+#include "sbeHostUtils.H"
+#include "sbeglobals.H"
#include "fapi2.H"
@@ -181,7 +183,33 @@ uint32_t processPbaRequest(const sbeMemAccessReqMsgHdr_t &i_hdr,
// Default for PBA
uint32_t l_granuleSize = PBA_GRAN_SIZE_BYTES;
- uint64_t l_addr = i_hdr.getAddr();
+ uint64_t l_addr = 0;
+
+ // If not Host Pass through command, simply set the addr from the command
+ if(!i_hdr.isPbaHostPassThroughModeSet())
+ {
+ l_addr = i_hdr.getAddr();
+ }
+ // If it is Host Pass through command, set the address using the Host pass
+ // through address already set in the global and using the addr here in the
+ // command as index to that address
+ else
+ {
+ l_addr = SBE_GLOBAL->hostPassThroughCmdAddr.addr + i_hdr.getAddr();
+ // Check if the size pass in the command is less than the size mentioned
+ // in the Host Pass Through globals
+ if((i_hdr.getAddr() + i_hdr.len) > SBE_GLOBAL->hostPassThroughCmdAddr.size)
+ {
+ // Break out, Invalid Size
+ SBE_ERROR("User size[0x%08X] exceeds the Host Pass Through Mode "
+ "size[0x%08X] Start Index[0x%08X %08X]",
+ i_hdr.len, SBE_GLOBAL->hostPassThroughCmdAddr.size,
+ SBE::higher32BWord(i_hdr.getAddr()),
+ SBE::lower32BWord(i_hdr.getAddr()));
+ l_respHdr.setStatus( SBE_PRI_INVALID_DATA,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION );
+ }
+ }
// Default EX Target Init..Not changing it for the time being
Target<TARGET_TYPE_EX> l_ex(
@@ -237,6 +265,12 @@ uint32_t processPbaRequest(const sbeMemAccessReqMsgHdr_t &i_hdr,
while (l_granulesCompleted < l_lenCacheAligned)
{
+ // Breaking out here if invalid size
+ if(l_respHdr.primaryStatus != SBE_PRI_OPERATION_SUCCESSFUL)
+ {
+ break;
+ }
+
// If this is putmem request, read input data from the upstream FIFO
if (!i_isFlagRead)
{
@@ -298,6 +332,11 @@ uint32_t processPbaRequest(const sbeMemAccessReqMsgHdr_t &i_hdr,
CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
l_rc = sbeDsSendRespHdr( l_respHdr, &l_ffdc);
+ // Indicate the host in put pass through mode via Interrupt
+ if(!l_rc && i_hdr.isPbaHostPassThroughModeSet() && !i_isFlagRead)
+ {
+ l_rc = sbeSetSbe2PsuDbBitX(SBE_SBE2PSU_DOORBELL_SET_BIT4);
+ }
} while(false);
SBE_EXIT(SBE_FUNC);
OpenPOWER on IntegriCloud