summaryrefslogtreecommitdiffstats
path: root/src/usr/util/runtime/rt_cmds.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/util/runtime/rt_cmds.C')
-rw-r--r--src/usr/util/runtime/rt_cmds.C222
1 files changed, 221 insertions, 1 deletions
diff --git a/src/usr/util/runtime/rt_cmds.C b/src/usr/util/runtime/rt_cmds.C
index e350e42dc..ce7df1daf 100644
--- a/src/usr/util/runtime/rt_cmds.C
+++ b/src/usr/util/runtime/rt_cmds.C
@@ -43,6 +43,9 @@
#include <isteps/pm/pm_common_ext.H>
#include <p9_hcd_memmap_base.H> // for reload_pm_complex
#include <p9_stop_data_struct.H> // for reload_pm_complex
+#include <scom/runtime/rt_scomif.H> // sendScomOpToFsp,
+ // sendMultiScomReadToFsp,
+ // switchToFspScomAccess
extern char hbi_ImageId;
@@ -994,6 +997,158 @@ void cmd_hbrt_update(char*& o_output)
/**
+ * @brief Mark a target as requiring access to its SCOMs through the FSP
+ * @param[out] o_output Output display buffer, memory allocated here
+ * @param[in] i_huid HUID associated with Target to switch access on
+ */
+void cmd_switchToFspScomAccess( char*& o_output, uint32_t i_huid)
+{
+ UTIL_FT( "cmd_switchToFspScomAccess> huid=%.8X", i_huid );
+
+ TARGETING::Target* l_targ{};
+
+ if(0xFFFFFFFF == i_huid)
+ {
+ TARGETING::targetService().getTopLevelTarget(l_targ);
+ }
+ else
+ {
+ l_targ = getTargetFromHUID(i_huid);
+ }
+
+ o_output = new char[100];
+ if( l_targ == NULL )
+ {
+ sprintf( o_output, "HUID %.8X not found", i_huid );
+ return;
+ }
+
+ FSISCOM::switchToFspScomAccess(l_targ);
+
+ sprintf( o_output, "switchToFspScomAccess executed");
+}
+
+
+/**
+ * @brief Send a scom operation (read/write) to the FSP
+ * @param[out] o_output Output display buffer, memory allocated here
+ * @param[in] i_op Operation: r or w
+ * @param[in] i_huid HUID associated with Target to get the SCOM from
+ * @param[in] i_scomAddr Address of SCOM to read or write
+ * @param[in] io_scomValue Buffer for read SCOM value, or value to write
+ */
+void cmd_sendScomOpToFSP( char*& o_output,
+ char i_op,
+ uint32_t i_huid,
+ uint64_t i_scomAddr,
+ uint64_t *io_scomValue )
+{
+ UTIL_FT( "cmd_getScomFromFSP> op=%c, huid=%.8X, addr=%.8X, size=%d",
+ i_op, i_huid, i_scomAddr, *io_scomValue );
+
+ TARGETING::Target* l_targ{};
+
+ if(0xFFFFFFFF == i_huid)
+ {
+ TARGETING::targetService().getTopLevelTarget(l_targ);
+ }
+ else
+ {
+ l_targ = getTargetFromHUID(i_huid);
+ }
+
+ o_output = new char[100];
+ if( l_targ == NULL )
+ {
+ sprintf( o_output, "HUID %.8X not found", i_huid );
+ return;
+ }
+
+ DeviceFW::OperationType l_op;
+ switch (i_op) {
+ case 'r':
+ case 'R':
+ l_op = DeviceFW::READ;
+ break;
+ case 'w':
+ case 'W':
+ l_op = DeviceFW::WRITE;
+ break;
+ default:
+ sprintf( o_output, "Operation must be r or w: %c", i_op );
+ return;
+ }
+
+ errlHndl_t l_err = nullptr;
+ l_err = FSISCOM::sendScomOpToFsp(l_op, l_targ, i_scomAddr,
+ (void *)io_scomValue);
+ if (l_err)
+ {
+ sprintf( o_output, "Error on call to sendScomOpToFsp, rc=%.4X",
+ ERRL_GETRC_SAFE(l_err) );
+ return;
+ }
+
+ sprintf( o_output, "op=%c, huid=%.16llX, scomAddr=%.16llX, scomValue=%.16llX",
+ i_op, i_huid, i_scomAddr, *io_scomValue);
+}
+
+
+/**
+ * @brief Send a multi scom read to the FSP
+ * @param[out] o_output Output display buffer, memory allocated here
+ * @param[in] i_huid HUID associated with Target to get the SCOMs from
+ * @param[in] i_scomAddr Addresses of SCOMs to read
+ * @param[in] o_scomValue Values of read SCOMs
+ */
+void cmd_sendMultiScomReadToFSP( char* &o_output,
+ uint32_t i_huid,
+ std::vector<uint64_t> &i_scomAddr,
+ std::vector<uint64_t> &o_scomValue )
+{
+ UTIL_FT( "cmd_sendMultiScomReadToFSP> huid=%.8X, num_SCOMs=%d,"
+ " num_outSCOMs=%d",
+ i_huid, i_scomAddr.size(), o_scomValue.size() );
+
+ TARGETING::Target* l_targ{};
+
+ if(0xFFFFFFFF == i_huid)
+ {
+ TARGETING::targetService().getTopLevelTarget(l_targ);
+ }
+ else
+ {
+ l_targ = getTargetFromHUID(i_huid);
+ }
+
+ o_output = new char[500];
+ if( l_targ == NULL )
+ {
+ sprintf( o_output, "HUID %.8X not found", i_huid );
+ return;
+ }
+
+ errlHndl_t l_err = nullptr;
+ l_err = FSISCOM::sendMultiScomReadToFsp( l_targ, i_scomAddr, o_scomValue);
+ if (l_err)
+ {
+ sprintf( o_output, "Error on call to sendMultiScomReadToFsp,"
+ " rc=%.4X", ERRL_GETRC_SAFE(l_err) );
+ return;
+ }
+
+ sprintf( o_output, "num_outSCOMs=%d", o_scomValue.size());
+ for (auto scom: o_scomValue)
+ {
+ char tmp_str[100];
+
+ sprintf( tmp_str, ", %.8llX", scom);
+ strcat( o_output, tmp_str);
+ }
+}
+
+
+/**
* @brief Execute an arbitrary command inside Hostboot Runtime
* @param[in] Number of arguments (standard C args)
* @param[in] Array of argument values (standard C args)
@@ -1254,9 +1409,67 @@ int hbrtCommand( int argc,
"ERROR: hbrt_update\n" );
}
}
+ else if( !strcmp( argv[0], "switchToFspScomAccess" ) )
+ {
+ if (argc == 2)
+ {
+ cmd_switchToFspScomAccess( *l_output,
+ strtou64(argv[1], NULL, 16)); // huid
+ }
+ else
+ {
+ *l_output = new char[100];
+ sprintf(*l_output,
+ "ERROR: switchToFspScomAccess <huid>");
+ }
+ }
+ else if( !strcmp( argv[0], "scomOpToFsp" ) )
+ {
+ if ((argc == 4) || (argc == 5))
+ {
+ uint64_t l_scomValue = 0;
+
+ if (argc == 5)
+ l_scomValue = strtou64( argv[4], NULL, 16 ); // value
+
+ cmd_sendScomOpToFSP( *l_output,
+ argv[1][0], // op
+ strtou64(argv[2], NULL, 16), // huid
+ strtou64(argv[3], NULL, 16), // addr
+ &l_scomValue );
+ }
+ else
+ {
+ *l_output = new char[100];
+ sprintf(*l_output,
+ "ERROR: scomOpToFsp <op> <huid> <scomAddr> [<scomValue>]");
+ }
+ }
+ else if( !strcmp( argv[0], "multiScomReadToFsp" ) )
+ {
+ if (argc >= 3)
+ {
+ std::vector<uint64_t> l_scomAddrs, l_scomValues;
+
+ for (int i = 2;i < argc;++i)
+ l_scomAddrs.push_back(strtou64( argv[i], NULL, 16 ));
+ l_scomValues.reserve(argc - 2);
+
+ cmd_sendMultiScomReadToFSP( *l_output,
+ strtou64(argv[1], NULL, 16), // huid
+ l_scomAddrs,
+ l_scomValues );
+ }
+ else
+ {
+ *l_output = new char[100];
+ sprintf(*l_output,
+ "ERROR: multiScomReadToFsp <huid> <scomAddrs>");
+ }
+ }
else
{
- *l_output = new char[50+100*10];
+ *l_output = new char[50+100*12];
char l_tmpstr[100];
sprintf( *l_output, "HBRT Commands:\n" );
sprintf( l_tmpstr, "testRunCommand <args...>\n" );
@@ -1283,6 +1496,13 @@ int hbrtCommand( int argc,
strcat( *l_output, l_tmpstr );
sprintf( l_tmpstr, "hbrt_update\n");
strcat( *l_output, l_tmpstr );
+ sprintf( l_tmpstr, "switchToFspScomAccess <huid>\n");
+ strcat( *l_output, l_tmpstr );
+ sprintf( l_tmpstr, "scomOpToFsp <op> <huid> <scomAddr> [<scomValue>]\n"
+ " <op> == r|w\n");
+ strcat( *l_output, l_tmpstr );
+ sprintf( l_tmpstr, "multiScomReadToFsp <huid> <scomAddrs>\n");
+ strcat( *l_output, l_tmpstr );
}
if( l_traceOut && (*l_output != NULL) )
OpenPOWER on IntegriCloud