summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/procedures/hwp/perv/p9_ram_core.C
diff options
context:
space:
mode:
authorLiuYangFan <shliuyf@cn.ibm.com>2016-04-01 03:25:41 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2016-08-01 11:56:29 -0400
commit47845536df2e76c019b1289fd72d443498b9c102 (patch)
tree4b2d9b3e1791d67ed90dd14c762ebbf490b1f853 /src/import/chips/p9/procedures/hwp/perv/p9_ram_core.C
parent28d4903c629357bca036b0fecb3cf3fb8a6e16a9 (diff)
downloadtalos-hostboot-47845536df2e76c019b1289fd72d443498b9c102.tar.gz
talos-hostboot-47845536df2e76c019b1289fd72d443498b9c102.zip
Update RAM procedures.
Changes included: p9_ram_core: 1. Add special case support for get/put NIA/MSR/CR/FPSCR 2. Add thread stop state check in setup 3. Add error handling when ram_setup/get_reg/put_reg p9_ram_get_all_reg/p9_ram_put_all_reg: Add get/put all registers function for test p9_ram_spr_test: New file to test SPR, verify with SPY read, for Cronus use p9_ram_after_checkstop: New file to test ram after checkstop p9_ram_addr_error_test: New file to test ram after bad address access p9_ram_wrap: Update to support the new tests Change-Id: Ia4da55eae26e9f3a667446bc984b358c064fdd8a Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/22746 Reviewed-by: Joseph J. McGill <jmcgill@us.ibm.com> Tested-by: Jenkins Server Reviewed-by: Thi N. Tran <thi@us.ibm.com> Tested-by: PPE CI Reviewed-by: PARVATHI RACHAKONDA <prachako@in.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/27696 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/perv/p9_ram_core.C')
-rw-r--r--src/import/chips/p9/procedures/hwp/perv/p9_ram_core.C647
1 files changed, 505 insertions, 142 deletions
diff --git a/src/import/chips/p9/procedures/hwp/perv/p9_ram_core.C b/src/import/chips/p9/procedures/hwp/perv/p9_ram_core.C
index 6553c03f8..b31b73ef2 100644
--- a/src/import/chips/p9/procedures/hwp/perv/p9_ram_core.C
+++ b/src/import/chips/p9/procedures/hwp/perv/p9_ram_core.C
@@ -24,7 +24,7 @@
//-----------------------------------------------------------------------------------
// *HWP HWP Owner : Liu Yang Fan <shliuyf@cn.ibm.com>
// *HWP HWP Backup Owner : Gou Peng Fei <shgoupf@cn.ibm.com>
-// *HWP FW Owner : Sachin Gupta <sgupta2m@in.ibm.com>
+// *HWP FW Owner : Thi Tran <thi@us.ibm.com>
// *HWP Team : Perv
// *HWP Level : 2
// *HWP Consumed by : SBE
@@ -35,19 +35,66 @@
#include "p9_quad_scom_addresses.H"
#include "p9_quad_scom_addresses_fld.H"
+// identifiers for special registers
+const uint32_t RAM_REG_NIA = 2000;
+const uint32_t RAM_REG_MSR = 2001;
+const uint32_t RAM_REG_CR = 2002;
+const uint32_t RAM_REG_FPSCR = 2003;
+
// opcode for ramming
-const uint32_t OPCODE_MTSPR_FROM_GPR0_TO_SPRD = 0x7C1543A6;
-const uint32_t OPCODE_MTSPR_FROM_GPR1_TO_SPRD = 0x7C3543A6;
-const uint32_t OPCODE_MFSPR_FROM_SPRD_TO_GPR0 = 0x7C1542A6;
-const uint32_t OPCODE_MFSPR_FROM_SPRD_TO_GPR1 = 0x7C3542A6;
-const uint32_t OPCODE_MFSPR_FROM_SPR0_TO_GPR0 = 0x7C0002A6;
-const uint32_t OPCODE_MTSPR_FROM_GPR0_TO_SPR0 = 0x7C0003A6;
-const uint32_t OPCODE_MFFPRD_FROM_FPR0_TO_GPR0 = 0x7C000066;
-const uint32_t OPCODE_MTFPRD_FROM_GPR0_TO_FPR0 = 0x7C000166;
-const uint32_t OPCODE_MFVSRD_FROM_VSR0_TO_GPR0 = 0x7C000067;
-const uint32_t OPCODE_MTVSRD_FROM_GPR0_TO_VSR0 = 0x7C000167;
-const uint32_t OPCODE_MFVSRLD_FROM_VSR0_TO_GPR0 = 0x7C000267;
-const uint32_t OPCODE_MTVSRDD_FROM_GPR1_0_TO_VSR0 = 0x7C010367;
+const uint32_t OPCODE_MTSPR_FROM_GPR0_TO_SPRD = 0x7C1543A6;
+const uint32_t OPCODE_MTSPR_FROM_GPR1_TO_SPRD = 0x7C3543A6;
+const uint32_t OPCODE_MFSPR_FROM_SPRD_TO_GPR0 = 0x7C1542A6;
+const uint32_t OPCODE_MFSPR_FROM_SPRD_TO_GPR1 = 0x7C3542A6;
+const uint32_t OPCODE_MFSPR_FROM_SPR0_TO_GPR0 = 0x7C0002A6;
+const uint32_t OPCODE_MTSPR_FROM_GPR0_TO_SPR0 = 0x7C0003A6;
+const uint32_t OPCODE_MFFPRD_FROM_FPR0_TO_GPR0 = 0x7C000066;
+const uint32_t OPCODE_MTFPRD_FROM_GPR0_TO_FPR0 = 0x7C000166;
+const uint32_t OPCODE_MFVSRD_FROM_VSR0_TO_GPR0 = 0x7C000066;
+const uint32_t OPCODE_MFVSRD_FROM_VSR32_TO_GPR0 = 0x7C000067;
+const uint32_t OPCODE_MFVSRLD_FROM_VSR0_TO_GPR0 = 0x7C000266;
+const uint32_t OPCODE_MFVSRLD_FROM_VSR32_TO_GPR0 = 0x7C000267;
+const uint32_t OPCODE_MTVSRDD_FROM_GPR1_0_TO_VSR0 = 0x7C010366;
+const uint32_t OPCODE_MTVSRDD_FROM_GPR1_0_TO_VSR32 = 0x7C010367;
+const uint32_t OPCODE_MFSPR_FROM_LR_TO_GPR0 = 0x7C0802A6;
+const uint32_t OPCODE_MTSPR_FROM_GPR0_TO_LR = 0x7C0803A6;
+const uint32_t OPCODE_MTMSR_L0 = 0x7C000124;
+const uint32_t OPCODE_MTMSRD_L0 = 0x7C000164;
+const uint32_t OPCODE_MTSPR_IAMR = 0x7C1D0BA6;
+const uint32_t OPCODE_MTSPR_PIDR = 0x7C100BA6;
+const uint32_t OPCODE_MTSPR_LPIDR = 0x7C1F4BA6;
+const uint32_t OPCODE_MTSPR_LPCR = 0x7C1E4BA6;
+const uint32_t OPCODE_MTSPR_MMCRA = 0x7C12C3A6;
+const uint32_t OPCODE_MTSPR_MMCR1 = 0x7C1EC3A6;
+const uint32_t OPCODE_MTSPR_SEIDBAR = 0x7C1F7BA6;
+const uint32_t OPCODE_MTSPR_XER = 0x7C0103A6;
+const uint32_t OPCODE_MFSPR_XER = 0x7C0102A6;
+const uint32_t OPCODE_MFFS = 0xFC00048E;
+const uint32_t OPCODE_SLBMFEE = 0x7C000726;
+const uint32_t OPCODE_SLBMFEV = 0x7C0006A6;
+const uint32_t OPCODE_DCBZ = 0x7C0007EC;
+const uint32_t OPCODE_DCBF = 0x7C0000AC;
+const uint32_t OPCODE_LD = 0xE8000000;
+const uint32_t OPCODE_STD = 0xF8000000;
+const uint32_t OPCODE_LFD = 0xC8000000;
+const uint32_t OPCODE_STFD = 0xD8000000;
+const uint32_t OPCODE_LVX = 0x7C0000CE;
+const uint32_t OPCODE_STVX = 0x7C0001CE;
+const uint32_t OPCODE_LXVD2X = 0x7C000698;
+const uint32_t OPCODE_STXVD2X = 0x7C000798;
+const uint32_t OPCODE_MFMSR_TO_GPR0 = 0x7C0000A6;
+const uint32_t OPCODE_MFCR_TO_GPR0 = 0x7C000026;
+const uint32_t OPCODE_MTCRF_FROM_GPR0 = 0x7C0FF120;
+const uint32_t OPCODE_MTFSF_FROM_GPR0 = 0xFE00058E;
+
+// TODO: make sure these special PPC are final version in PC workbook table 9-2
+const uint32_t OPCODE_MFNIA_RT = 0x001ac804;
+const uint32_t OPCODE_MTNIA_LR = 0x4c1e00a4;
+const uint32_t OPCODE_GPR_MOVE = 0x00000010;
+const uint32_t OPCODE_VSR_MOVE_HI = 0x00000110;
+const uint32_t OPCODE_VSR_MOVE_LO = 0x00000210;
+const uint32_t OPCODE_XER_MOVE = 0x00000310;
+const uint32_t OPCODE_CR_MOVE = 0x00000410;
// poll count for check ram status
const uint32_t RAM_CORE_STAT_POLL_CNT = 10;
@@ -55,6 +102,7 @@ const uint32_t RAM_CORE_STAT_POLL_CNT = 10;
// Scom register field
// TODO: replace the const with FLD macro define when it's ready
const uint32_t C_RAM_MODEREG_ENABLE = 0;
+const uint32_t C_RAS_STATUS_CORE_MAINT = 0;
const uint32_t C_THREAD_INFO_VTID0_ACTIVE = 0;
const uint32_t C_RAM_CTRL_VTID = 0;
const uint32_t C_RAM_CTRL_VTID_LEN = 2;
@@ -74,13 +122,15 @@ RamCore::RamCore(const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target, const u
{
iv_target = i_target;
iv_thread = i_thread;
- iv_ram_enable = false;
- iv_ram_setup = false;
- iv_write_gpr0 = false;
- iv_write_gpr1 = false;
- iv_backup_buf0 = 0;
- iv_backup_buf1 = 0;
- iv_backup_buf2 = 0;
+ iv_ram_enable = false;
+ iv_ram_scr0_save = false;
+ iv_ram_setup = false;
+ iv_ram_err = false;
+ iv_write_gpr0 = false;
+ iv_write_gpr1 = false;
+ iv_backup_buf0 = 0;
+ iv_backup_buf1 = 0;
+ iv_backup_buf2 = 0;
}
RamCore::~RamCore()
@@ -94,16 +144,28 @@ RamCore::~RamCore()
//-----------------------------------------------------------------------------------
fapi2::ReturnCode RamCore::ram_setup()
{
- FAPI_INF("Start ram setup");
+ FAPI_DBG("Start ram setup");
fapi2::buffer<uint64_t> l_data = 0;
uint32_t l_opcode = 0;
bool l_thread_active = false;
+ uint8_t l_thread_stop = 0;
// set RAM_MODEREG Scom to enable RAM mode
FAPI_TRY(fapi2::getScom(iv_target, C_RAM_MODEREG, l_data));
l_data.setBit<C_RAM_MODEREG_ENABLE>();
FAPI_TRY(fapi2::putScom(iv_target, C_RAM_MODEREG, l_data));
+ // read RAS_STATUS Scom to check the thread is stopped for ramming
+ l_data.flush<0>();
+ FAPI_TRY(fapi2::getScom(iv_target, C_RAS_STATUS, l_data));
+ FAPI_DBG("RAS_STATUS:%#lx", l_data());
+ FAPI_TRY(l_data.extractToRight(l_thread_stop, C_RAS_STATUS_CORE_MAINT + 8 * iv_thread, 2));
+
+ FAPI_ASSERT(l_thread_stop == 3,
+ fapi2::P9_RAM_THREAD_NOT_STOP_ERR()
+ .set_THREAD(iv_thread),
+ "Thread to perform ram is not stopped");
+
// read THREAD_INFO Scom to check the thread is active for ramming
l_data.flush<0>();
FAPI_TRY(fapi2::getScom(iv_target, C_THREAD_INFO, l_data));
@@ -117,9 +179,10 @@ fapi2::ReturnCode RamCore::ram_setup()
iv_ram_enable = true;
- // backup registers SCR0/GPR0/GPR1
+ // backup registers SCR0/GPR0/GPR1/LR
//SCR0->iv_backup_buf0
FAPI_TRY(fapi2::getScom(iv_target, C_SCR0, iv_backup_buf0));
+ iv_ram_scr0_save = true;
//GPR0->iv_backup_buf1
//1.setup SPRC to use SCRO as SPRD
@@ -150,14 +213,22 @@ fapi2::ReturnCode RamCore::ram_setup()
iv_ram_setup = true;
fapi_try_exit:
- FAPI_INF("Exiting ram setup");
+
+ // Error happened and SCR0 saved, to restore SCR0
+ // Do not use "FAPI_TRY" to avoid endless loop
+ if((fapi2::current_err != fapi2::FAPI2_RC_SUCCESS) && iv_ram_scr0_save)
+ {
+ fapi2::putScom(iv_target, C_SCR0, iv_backup_buf0);
+ }
+
+ FAPI_DBG("Exiting ram setup");
return fapi2::current_err;
}
//-----------------------------------------------------------------------------------
fapi2::ReturnCode RamCore::ram_cleanup()
{
- FAPI_INF("Start ram cleanup");
+ FAPI_DBG("Start ram cleanup");
uint32_t l_opcode = 0;
fapi2::buffer<uint64_t> l_data = 0;
@@ -165,26 +236,30 @@ fapi2::ReturnCode RamCore::ram_cleanup()
fapi2::P9_RAM_NOT_SETUP_ERR(),
"Attempting to cleanup ram without setup before");
- // restore GPR1/GPR0/SCR0
- if(!iv_write_gpr0 && !iv_write_gpr1)
+ // setup SPRC to use SCRO as SPRD
+ FAPI_TRY(fapi2::getScom(iv_target, C_SPR_MODE, l_data));
+ FAPI_TRY(l_data.setBit(C_SPR_MODE_MODEREG_SPRC_LT0_SEL + iv_thread));
+ FAPI_TRY(fapi2::putScom(iv_target, C_SPR_MODE, l_data));
+ l_data.flush<0>();
+ FAPI_TRY(fapi2::getScom(iv_target, C_SCOMC, l_data));
+ l_data.insertFromRight<C_SCOMC_MODE, C_SCOMC_MODE_LEN>(0);
+ FAPI_TRY(fapi2::putScom(iv_target, C_SCOMC, l_data));
+
+ // restore GPR1
+ if(!iv_write_gpr1)
{
//iv_backup_buf2->GPR1
- //1.setup SPRC to use SCRO as SPRD
- FAPI_TRY(fapi2::getScom(iv_target, C_SPR_MODE, l_data));
- FAPI_TRY(l_data.setBit(C_SPR_MODE_MODEREG_SPRC_LT0_SEL + iv_thread));
- FAPI_TRY(fapi2::putScom(iv_target, C_SPR_MODE, l_data));
- l_data.flush<0>();
- FAPI_TRY(fapi2::getScom(iv_target, C_SCOMC, l_data));
- l_data.insertFromRight<C_SCOMC_MODE, C_SCOMC_MODE_LEN>(0);
- FAPI_TRY(fapi2::putScom(iv_target, C_SCOMC, l_data));
-
- //2.put restore data into SCR0
+ //1.put restore data into SCR0
FAPI_TRY(fapi2::putScom(iv_target, C_SCR0, iv_backup_buf2));
- //3.create mfsprd<gpr1> opcode, ram into thread to restore GPR1
+ //2.create mfsprd<gpr1> opcode, ram into thread to restore GPR1
l_opcode = OPCODE_MFSPR_FROM_SPRD_TO_GPR1;
FAPI_TRY(ram_opcode(l_opcode, true));
+ }
+ // restore GPR0
+ if(!iv_write_gpr0)
+ {
//iv_backup_buf1->GPR0
//1.put restore data into SCR0
FAPI_TRY(fapi2::putScom(iv_target, C_SCR0, iv_backup_buf1));
@@ -192,62 +267,10 @@ fapi2::ReturnCode RamCore::ram_cleanup()
//2.create mfsprd<gpr0> opcode, ram into thread to restore GPR0
l_opcode = OPCODE_MFSPR_FROM_SPRD_TO_GPR0;
FAPI_TRY(ram_opcode(l_opcode, true));
-
- //iv_backup_buf0->SCR0
- FAPI_TRY(fapi2::putScom(iv_target, C_SCR0, iv_backup_buf0));
- }
- // restore GPR0/SCR0
- else if(!iv_write_gpr0 && iv_write_gpr1)
- {
- //iv_backup_buf1->GPR0
- //1.setup SPRC to use SCRO as SPRD
- FAPI_TRY(fapi2::getScom(iv_target, C_SPR_MODE, l_data));
- FAPI_TRY(l_data.setBit(C_SPR_MODE_MODEREG_SPRC_LT0_SEL + iv_thread));
- FAPI_TRY(fapi2::putScom(iv_target, C_SPR_MODE, l_data));
- l_data.flush<0>();
- FAPI_TRY(fapi2::getScom(iv_target, C_SCOMC, l_data));
- l_data.insertFromRight<C_SCOMC_MODE, C_SCOMC_MODE_LEN>(0);
- FAPI_TRY(fapi2::putScom(iv_target, C_SCOMC, l_data));
-
- //2.put restore data into SCR0
- FAPI_TRY(fapi2::putScom(iv_target, C_SCR0, iv_backup_buf1));
-
- //3.create mfsprd<gpr0> opcode, ram into thread to restore GPR0
- l_opcode = OPCODE_MFSPR_FROM_SPRD_TO_GPR0;
- FAPI_TRY(ram_opcode(l_opcode, true));
-
- //iv_backup_buf0->SCR0
- FAPI_TRY(fapi2::putScom(iv_target, C_SCR0, iv_backup_buf0));
}
- // restore GPR1/SCR0
- else if(iv_write_gpr0 && !iv_write_gpr1)
- {
- //iv_backup_buf2->GPR1
- //1.setup SPRC to use SCRO as SPRD
- FAPI_TRY(fapi2::getScom(iv_target, C_SPR_MODE, l_data));
- FAPI_TRY(l_data.setBit(C_SPR_MODE_MODEREG_SPRC_LT0_SEL + iv_thread));
- FAPI_TRY(fapi2::putScom(iv_target, C_SPR_MODE, l_data));
- l_data.flush<0>();
- FAPI_TRY(fapi2::getScom(iv_target, C_SCOMC, l_data));
- l_data.insertFromRight<C_SCOMC_MODE, C_SCOMC_MODE_LEN>(0);
- FAPI_TRY(fapi2::putScom(iv_target, C_SCOMC, l_data));
-
- //2.put restore data into SCR0
- FAPI_TRY(fapi2::putScom(iv_target, C_SCR0, iv_backup_buf2));
- //3.create mfsprd<gpr0> opcode, ram into thread to restore GPR1
- l_opcode = OPCODE_MFSPR_FROM_SPRD_TO_GPR1;
- FAPI_TRY(ram_opcode(l_opcode, true));
-
- //iv_backup_buf0->SCR0
- FAPI_TRY(fapi2::putScom(iv_target, C_SCR0, iv_backup_buf0));
- }
- // restore SCR0
- else
- {
- //iv_backup_buf0->SCR0
- FAPI_TRY(fapi2::putScom(iv_target, C_SCR0, iv_backup_buf0));
- }
+ //iv_backup_buf0->SCR0
+ FAPI_TRY(fapi2::putScom(iv_target, C_SCR0, iv_backup_buf0));
// set RAM_MODEREG Scom to clear RAM mode
l_data.flush<0>();
@@ -255,23 +278,24 @@ fapi2::ReturnCode RamCore::ram_cleanup()
l_data.clearBit<C_RAM_MODEREG_ENABLE>();
FAPI_TRY(fapi2::putScom(iv_target, C_RAM_MODEREG, l_data));
- iv_ram_enable = false;
- iv_ram_setup = false;
- iv_write_gpr0 = false;
- iv_write_gpr1 = false;
+ iv_ram_enable = false;
+ iv_ram_scr0_save = false;
+ iv_ram_setup = false;
+ iv_write_gpr0 = false;
+ iv_write_gpr1 = false;
fapi_try_exit:
- FAPI_INF("Exiting ram cleanup");
+ FAPI_DBG("Exiting ram cleanup");
return fapi2::current_err;
}
//-----------------------------------------------------------------------------------
fapi2::ReturnCode RamCore::ram_opcode(const uint32_t i_opcode, const bool i_allow_mult)
{
- FAPI_INF("Start ram opcode");
+ FAPI_DBG("Start ram opcode");
fapi2::buffer<uint64_t> l_data = 0;
- uint8_t l_predecode = 0;
- uint8_t l_poll_count = RAM_CORE_STAT_POLL_CNT;
+ uint8_t l_predecode = 0;
+ uint32_t l_poll_count = RAM_CORE_STAT_POLL_CNT;
bool l_is_load_store = false;
// check the opcode for load/store
@@ -343,32 +367,94 @@ fapi2::ReturnCode RamCore::ram_opcode(const uint32_t i_opcode, const bool i_allo
}
fapi_try_exit:
- FAPI_INF("Exiting ram opcode");
+
+ if(fapi2::current_err != fapi2::FAPI2_RC_SUCCESS)
+ {
+ iv_ram_err = true;
+ }
+
+ FAPI_DBG("Exiting ram opcode");
return fapi2::current_err;
}
//-----------------------------------------------------------------------------------
uint8_t RamCore::gen_predecode(const uint32_t i_opcode)
{
- //TODO: implement when the PC workbook is updated
- return 0;
+ //TODO: make sure they are final version in PC workbook table 9-1 and 9-2
+ uint8_t l_predecode = 0;
+ uint32_t l_opcode_pattern0 = i_opcode & 0xFC0007FE;
+ uint32_t l_opcode_pattern1 = i_opcode & 0xFC1FFFFE;
+
+ if((i_opcode == OPCODE_MFNIA_RT) ||
+ (i_opcode == OPCODE_GPR_MOVE) ||
+ (i_opcode == OPCODE_VSR_MOVE_HI) ||
+ (i_opcode == OPCODE_VSR_MOVE_LO) ||
+ (i_opcode == OPCODE_XER_MOVE) ||
+ (i_opcode == OPCODE_CR_MOVE))
+ {
+ l_predecode = 2;
+ }
+ else if((i_opcode == OPCODE_MTNIA_LR) ||
+ (l_opcode_pattern0 == OPCODE_MTMSR_L0) ||
+ (l_opcode_pattern0 == OPCODE_MTMSRD_L0))
+ {
+ l_predecode = 8;
+ }
+ else if((l_opcode_pattern1 == OPCODE_MTSPR_IAMR) ||
+ (l_opcode_pattern1 == OPCODE_MTSPR_PIDR) ||
+ (l_opcode_pattern1 == OPCODE_MTSPR_LPIDR) ||
+ (l_opcode_pattern1 == OPCODE_MTSPR_LPCR) ||
+ (l_opcode_pattern1 == OPCODE_MTSPR_MMCRA) ||
+ (l_opcode_pattern1 == OPCODE_MTSPR_MMCR1) ||
+ (l_opcode_pattern1 == OPCODE_MTSPR_SEIDBAR) ||
+ (l_opcode_pattern1 == OPCODE_MTSPR_XER) ||
+ (l_opcode_pattern1 == OPCODE_MFSPR_XER) ||
+ (l_opcode_pattern0 == OPCODE_MFFS) ||
+ (l_opcode_pattern0 == OPCODE_SLBMFEE) ||
+ (l_opcode_pattern0 == OPCODE_SLBMFEV))
+ {
+ l_predecode = 4;
+ }
+
+ return l_predecode;
}
//-----------------------------------------------------------------------------------
bool RamCore::is_load_store(const uint32_t i_opcode)
{
- //TODO: implement when the PC workbook is updated
- return false;
+ //TODO: make sure they are final version in PC workbook table 9-1
+ bool l_load_store = false;
+ uint32_t l_opcode_pattern0 = i_opcode & 0xFC0007FE;
+ uint32_t l_opcode_pattern1 = i_opcode & 0xFC000000;
+
+ if((l_opcode_pattern0 == OPCODE_DCBZ) ||
+ (l_opcode_pattern0 == OPCODE_DCBF) ||
+ (l_opcode_pattern1 == OPCODE_LD) ||
+ (l_opcode_pattern1 == OPCODE_LFD) ||
+ (l_opcode_pattern1 == OPCODE_STD) ||
+ (l_opcode_pattern1 == OPCODE_LFD) ||
+ (l_opcode_pattern1 == OPCODE_STFD) ||
+ (l_opcode_pattern0 == OPCODE_LVX) ||
+ (l_opcode_pattern0 == OPCODE_STVX) ||
+ (l_opcode_pattern0 == OPCODE_LXVD2X) ||
+ (l_opcode_pattern0 == OPCODE_STXVD2X))
+ {
+ l_load_store = true;
+ }
+
+ return l_load_store;
}
//-----------------------------------------------------------------------------------
fapi2::ReturnCode RamCore::get_reg(const Enum_RegType i_type, const uint32_t i_reg_num,
fapi2::buffer<uint64_t>* o_buffer, const bool i_allow_mult)
{
- FAPI_INF("Start get register");
+ FAPI_DBG("Start get register");
uint32_t l_opcode = 0;
uint32_t l_spr_regnum_lo = 0;
uint32_t l_spr_regnum_hi = 0;
+ fapi2::buffer<uint64_t> l_backup_gpr0 = 0;
+ fapi2::buffer<uint64_t> l_backup_fpr0 = 0;
// ram_setup
if(!i_allow_mult)
@@ -380,6 +466,14 @@ fapi2::ReturnCode RamCore::get_reg(const Enum_RegType i_type, const uint32_t i_r
fapi2::P9_RAM_NOT_SETUP_ERR(),
"Attempting to get register without setup before");
+ //backup GPR0 if it is written
+ if(iv_write_gpr0)
+ {
+ l_opcode = OPCODE_MTSPR_FROM_GPR0_TO_SPRD;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+ FAPI_TRY(fapi2::getScom(iv_target, C_SCR0, l_backup_gpr0));
+ }
+
// get register value
if(i_type == REG_GPR)
{
@@ -393,20 +487,88 @@ fapi2::ReturnCode RamCore::get_reg(const Enum_RegType i_type, const uint32_t i_r
}
else if(i_type == REG_SPR)
{
- //1.create mfspr<gpr0, i_reg_num> opcode, ram into thread
- l_opcode = OPCODE_MFSPR_FROM_SPR0_TO_GPR0;
- l_spr_regnum_lo = i_reg_num & 0x0000001F;
- l_spr_regnum_hi = i_reg_num & 0x000003E0;
- l_opcode += (l_spr_regnum_lo << 16);
- l_opcode += (l_spr_regnum_hi << 11);
- FAPI_TRY(ram_opcode(l_opcode, true));
+ if(i_reg_num == RAM_REG_NIA)
+ {
+ //1.ram MFNIA_RT opcode
+ l_opcode = OPCODE_MFNIA_RT;
+ FAPI_TRY(ram_opcode(l_opcode, true));
- //2.create mtsprd<gpr0> opcode, ram into thread
- l_opcode = OPCODE_MTSPR_FROM_GPR0_TO_SPRD;
- FAPI_TRY(ram_opcode(l_opcode, true));
+ //2.get NIA from GPR0
+ l_opcode = OPCODE_MTSPR_FROM_GPR0_TO_SPRD;
+ FAPI_TRY(ram_opcode(l_opcode, true));
- //3.get GPR value from SCR0
- FAPI_TRY(fapi2::getScom(iv_target, C_SCR0, o_buffer[0]));
+ FAPI_TRY(fapi2::getScom(iv_target, C_SCR0, o_buffer[0]));
+ }
+ else if(i_reg_num == RAM_REG_MSR)
+ {
+ //1.create mfmsr opcode, ram into thread
+ l_opcode = OPCODE_MFMSR_TO_GPR0;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+
+ //2.get MSR value from SCR0
+ l_opcode = OPCODE_MTSPR_FROM_GPR0_TO_SPRD;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+
+ FAPI_TRY(fapi2::getScom(iv_target, C_SCR0, o_buffer[0]));
+ }
+ else if(i_reg_num == RAM_REG_CR)
+ {
+ //1.create mfcr opcode, ram into thread
+ l_opcode = OPCODE_MFCR_TO_GPR0;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+
+ //2.get MSR value from SCR0
+ l_opcode = OPCODE_MTSPR_FROM_GPR0_TO_SPRD;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+
+ FAPI_TRY(fapi2::getScom(iv_target, C_SCR0, o_buffer[0]));
+ }
+ else if(i_reg_num == RAM_REG_FPSCR)
+ {
+ //1.backup FPR0
+ l_opcode = OPCODE_MFFPRD_FROM_FPR0_TO_GPR0;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+
+ l_opcode = OPCODE_MTSPR_FROM_GPR0_TO_SPRD;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+
+ FAPI_TRY(fapi2::getScom(iv_target, C_SCR0, l_backup_fpr0));
+
+ //2.create mffs opcode, ram into thread
+ l_opcode = OPCODE_MFFS;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+
+ //3.get FPSCR value from SCR0
+ l_opcode = OPCODE_MTSPR_FROM_GPR0_TO_SPRD;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+
+ FAPI_TRY(fapi2::getScom(iv_target, C_SCR0, o_buffer[0]));
+
+ //4.restore FPR0
+ FAPI_TRY(fapi2::putScom(iv_target, C_SCR0, l_backup_fpr0));
+ l_opcode = OPCODE_MFSPR_FROM_SPRD_TO_GPR0;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+
+ l_opcode = OPCODE_MTFPRD_FROM_GPR0_TO_FPR0;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+ }
+ else
+ {
+ //1.create mfspr<gpr0, i_reg_num> opcode, ram into thread
+ l_opcode = OPCODE_MFSPR_FROM_SPR0_TO_GPR0;
+ l_spr_regnum_lo = i_reg_num & 0x0000001F;
+ l_spr_regnum_hi = i_reg_num & 0x000003E0;
+ l_opcode += (l_spr_regnum_lo << 16);
+ l_opcode += (l_spr_regnum_hi << 6);
+ FAPI_TRY(ram_opcode(l_opcode, true));
+
+ //2.create mtsprd<gpr0> opcode, ram into thread
+ l_opcode = OPCODE_MTSPR_FROM_GPR0_TO_SPRD;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+
+ //3.get GPR value from SCR0
+ FAPI_TRY(fapi2::getScom(iv_target, C_SCR0, o_buffer[0]));
+ }
}
else if(i_type == REG_FPR)
{
@@ -422,11 +584,22 @@ fapi2::ReturnCode RamCore::get_reg(const Enum_RegType i_type, const uint32_t i_r
//3.get GPR value from SCR0
FAPI_TRY(fapi2::getScom(iv_target, C_SCR0, o_buffer[0]));
}
+
+#ifndef __PPE__
else if(i_type == REG_VSR)
{
- //1.create mfvsrd<gpr0, i_reg_num>#SX=1 opcode, ram into thread to get dw0
- l_opcode = OPCODE_MFVSRD_FROM_VSR0_TO_GPR0;
- l_opcode += (i_reg_num << 21);
+ //1.create mfvsrd<gpr0, i_reg_num> opcode, ram into thread to get dw0
+ if(i_reg_num < 32)
+ {
+ l_opcode = OPCODE_MFVSRD_FROM_VSR0_TO_GPR0;
+ l_opcode += (i_reg_num << 21);
+ }
+ else
+ {
+ l_opcode = OPCODE_MFVSRD_FROM_VSR32_TO_GPR0;
+ l_opcode += ((i_reg_num - 32) << 21);
+ }
+
FAPI_TRY(ram_opcode(l_opcode, true));
//2.create mtsprd<gpr0> opcode, ram into thread
@@ -436,9 +609,18 @@ fapi2::ReturnCode RamCore::get_reg(const Enum_RegType i_type, const uint32_t i_r
//3.get VSR dw0 value from SCR0
FAPI_TRY(fapi2::getScom(iv_target, C_SCR0, o_buffer[0]));
- //4.create mfvrld<gpr0, i_reg_num>#SX=1 opcode, ram into thread to get dw1
- l_opcode = OPCODE_MFVSRLD_FROM_VSR0_TO_GPR0;
- l_opcode += (i_reg_num << 21);
+ //4.create mfvrld<gpr0, i_reg_num> opcode, ram into thread to get dw1
+ if(i_reg_num < 32)
+ {
+ l_opcode = OPCODE_MFVSRLD_FROM_VSR0_TO_GPR0;
+ l_opcode += (i_reg_num << 21);
+ }
+ else
+ {
+ l_opcode = OPCODE_MFVSRLD_FROM_VSR32_TO_GPR0;
+ l_opcode += ((i_reg_num - 32) << 21);
+ }
+
FAPI_TRY(ram_opcode(l_opcode, true));
//5.create mtsprd<gpr0> opcode, ram into thread
@@ -448,6 +630,8 @@ fapi2::ReturnCode RamCore::get_reg(const Enum_RegType i_type, const uint32_t i_r
//6.get VSR dw1 value from SCR0
FAPI_TRY(fapi2::getScom(iv_target, C_SCR0, o_buffer[1]));
}
+
+#endif
else
{
FAPI_ASSERT(false,
@@ -456,6 +640,14 @@ fapi2::ReturnCode RamCore::get_reg(const Enum_RegType i_type, const uint32_t i_r
"Type of reg is not supported");
}
+ //restore GPR0 if necessary
+ if(iv_write_gpr0)
+ {
+ FAPI_TRY(fapi2::putScom(iv_target, C_SCR0, l_backup_gpr0));
+ l_opcode = OPCODE_MFSPR_FROM_SPRD_TO_GPR0;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+ }
+
// ram_cleanup
if(!i_allow_mult)
{
@@ -463,18 +655,33 @@ fapi2::ReturnCode RamCore::get_reg(const Enum_RegType i_type, const uint32_t i_r
}
fapi_try_exit:
- FAPI_INF("Exiting get register");
- return fapi2::current_err;
+ // Error happened and it's not ram error, call ram_cleanup to restore the backup registers
+ // If it is ram error, do not call ram_cleanup, so that no new ramming will be executed
+ // Do not use "FAPI_TRY" to avoid endless loop
+ fapi2::ReturnCode first_err = fapi2::current_err;
+
+ if((fapi2::current_err != fapi2::FAPI2_RC_SUCCESS) && !iv_ram_err && iv_ram_setup)
+ {
+ ram_cleanup();
+ }
+
+ FAPI_DBG("Exiting get register");
+ return first_err;
}
//-----------------------------------------------------------------------------------
fapi2::ReturnCode RamCore::put_reg(const Enum_RegType i_type, const uint32_t i_reg_num,
const fapi2::buffer<uint64_t>* i_buffer, const bool i_allow_mult)
{
- FAPI_INF("Start put register");
+ FAPI_DBG("Start put register");
uint32_t l_opcode = 0;
uint32_t l_spr_regnum_lo = 0;
uint32_t l_spr_regnum_hi = 0;
+ bool l_write_gpr0 = false;
+ fapi2::buffer<uint64_t> l_backup_lr = 0;
+ fapi2::buffer<uint64_t> l_backup_gpr0 = 0;
+ fapi2::buffer<uint64_t> l_backup_gpr1 = 0;
+ fapi2::buffer<uint64_t> l_backup_fpr0 = 0;
// ram_setup
if(!i_allow_mult)
@@ -486,6 +693,26 @@ fapi2::ReturnCode RamCore::put_reg(const Enum_RegType i_type, const uint32_t i_r
fapi2::P9_RAM_NOT_SETUP_ERR(),
"Attempting to put register without setup before");
+ //backup GPR0 if it is written
+ if(iv_write_gpr0)
+ {
+ l_opcode = OPCODE_MTSPR_FROM_GPR0_TO_SPRD;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+ FAPI_TRY(fapi2::getScom(iv_target, C_SCR0, l_backup_gpr0));
+ }
+
+#ifndef __PPE__
+
+ //backup GPR1 if it is written
+ if(iv_write_gpr1 && (i_type == REG_VSR))
+ {
+ l_opcode = OPCODE_MTSPR_FROM_GPR1_TO_SPRD;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+ FAPI_TRY(fapi2::getScom(iv_target, C_SCR0, l_backup_gpr1));
+ }
+
+#endif
+
// put register value
if(i_type == REG_GPR)
{
@@ -500,6 +727,7 @@ fapi2::ReturnCode RamCore::put_reg(const Enum_RegType i_type, const uint32_t i_r
if(i_reg_num == 0)
{
iv_write_gpr0 = true;
+ l_write_gpr0 = true;
}
if(i_reg_num == 1)
@@ -509,20 +737,111 @@ fapi2::ReturnCode RamCore::put_reg(const Enum_RegType i_type, const uint32_t i_r
}
else if(i_type == REG_SPR)
{
- //1.put SPR value into SCR0
- FAPI_TRY(fapi2::putScom(iv_target, C_SCR0, i_buffer[0]));
+ if(i_reg_num == RAM_REG_NIA)
+ {
+ //1.backup LR
+ l_opcode = OPCODE_MFSPR_FROM_LR_TO_GPR0;
+ FAPI_TRY(ram_opcode(l_opcode, true));
- //2.create mfsprd<gpr0> opcode, ram into thread
- l_opcode = OPCODE_MFSPR_FROM_SPRD_TO_GPR0;
- FAPI_TRY(ram_opcode(l_opcode, true));
+ l_opcode = OPCODE_MTSPR_FROM_GPR0_TO_SPRD;
+ FAPI_TRY(ram_opcode(l_opcode, true));
- //3.create mtspr<i_reg_num, gpr0> opcode, ram into thread
- l_opcode = OPCODE_MTSPR_FROM_GPR0_TO_SPR0;
- l_spr_regnum_lo = i_reg_num & 0x0000001F;
- l_spr_regnum_hi = i_reg_num & 0x000003E0;
- l_opcode += (l_spr_regnum_lo << 16);
- l_opcode += (l_spr_regnum_hi << 11);
- FAPI_TRY(ram_opcode(l_opcode, true));
+ FAPI_TRY(fapi2::getScom(iv_target, C_SCR0, l_backup_lr));
+
+ //2.put NIA value into LR
+ FAPI_TRY(fapi2::putScom(iv_target, C_SCR0, i_buffer[0]));
+
+ l_opcode = OPCODE_MFSPR_FROM_SPRD_TO_GPR0;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+
+ l_opcode = OPCODE_MTSPR_FROM_GPR0_TO_LR;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+
+ //3.ram MTNIA_LR opcode
+ l_opcode = OPCODE_MTNIA_LR;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+
+ //4.restore LR
+ FAPI_TRY(fapi2::putScom(iv_target, C_SCR0, l_backup_lr));
+
+ l_opcode = OPCODE_MFSPR_FROM_SPRD_TO_GPR0;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+
+ l_opcode = OPCODE_MTSPR_FROM_GPR0_TO_LR;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+ }
+ else if(i_reg_num == RAM_REG_MSR)
+ {
+ //1.put SPR value into SCR0
+ FAPI_TRY(fapi2::putScom(iv_target, C_SCR0, i_buffer[0]));
+
+ //2.create mfsprd<gpr0> opcode, ram into thread
+ l_opcode = OPCODE_MFSPR_FROM_SPRD_TO_GPR0;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+
+ //3.create mtmsrd opcode, ram into thread
+ l_opcode = OPCODE_MTMSRD_L0;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+ }
+ else if(i_reg_num == RAM_REG_CR)
+ {
+ //1.put SPR value into SCR0
+ FAPI_TRY(fapi2::putScom(iv_target, C_SCR0, i_buffer[0]));
+
+ //2.create mfsprd<gpr0> opcode, ram into thread
+ l_opcode = OPCODE_MFSPR_FROM_SPRD_TO_GPR0;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+
+ //3.create mtcrf opcode, ram into thread
+ l_opcode = OPCODE_MTCRF_FROM_GPR0;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+ }
+ else if(i_reg_num == RAM_REG_FPSCR)
+ {
+ //1.backup FPR0
+ l_opcode = OPCODE_MFFPRD_FROM_FPR0_TO_GPR0;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+
+ l_opcode = OPCODE_MTSPR_FROM_GPR0_TO_SPRD;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+
+ FAPI_TRY(fapi2::getScom(iv_target, C_SCR0, l_backup_fpr0));
+
+ //2.put SPR value into GPR0
+ FAPI_TRY(fapi2::putScom(iv_target, C_SCR0, i_buffer[0]));
+
+ l_opcode = OPCODE_MFSPR_FROM_SPRD_TO_GPR0;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+
+ //3.create mtfsf opcode, ram into thread
+ l_opcode = OPCODE_MTFSF_FROM_GPR0;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+
+ //4.restore FPR0
+ FAPI_TRY(fapi2::putScom(iv_target, C_SCR0, l_backup_fpr0));
+ l_opcode = OPCODE_MFSPR_FROM_SPRD_TO_GPR0;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+
+ l_opcode = OPCODE_MTFPRD_FROM_GPR0_TO_FPR0;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+ }
+ else
+ {
+ //1.put SPR value into SCR0
+ FAPI_TRY(fapi2::putScom(iv_target, C_SCR0, i_buffer[0]));
+
+ //2.create mfsprd<gpr0> opcode, ram into thread
+ l_opcode = OPCODE_MFSPR_FROM_SPRD_TO_GPR0;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+
+ //3.create mtspr<i_reg_num, gpr0> opcode, ram into thread
+ l_opcode = OPCODE_MTSPR_FROM_GPR0_TO_SPR0;
+ l_spr_regnum_lo = i_reg_num & 0x0000001F;
+ l_spr_regnum_hi = i_reg_num & 0x000003E0;
+ l_opcode += (l_spr_regnum_lo << 16);
+ l_opcode += (l_spr_regnum_hi << 6);
+ FAPI_TRY(ram_opcode(l_opcode, true));
+ }
}
else if(i_type == REG_FPR)
{
@@ -538,6 +857,8 @@ fapi2::ReturnCode RamCore::put_reg(const Enum_RegType i_type, const uint32_t i_r
l_opcode += (i_reg_num << 21);
FAPI_TRY(ram_opcode(l_opcode, true));
}
+
+#ifndef __PPE__
else if(i_type == REG_VSR)
{
//1.put VSR dw1 value into SCR0
@@ -556,10 +877,21 @@ fapi2::ReturnCode RamCore::put_reg(const Enum_RegType i_type, const uint32_t i_r
FAPI_TRY(ram_opcode(l_opcode, true));
//5.create mtvsrdd<i_reg_num, gpr0, gpr1> opcode, ram into thread
- l_opcode = OPCODE_MTVSRDD_FROM_GPR1_0_TO_VSR0;
- l_opcode += (i_reg_num << 21);
+ if(i_reg_num < 32)
+ {
+ l_opcode = OPCODE_MTVSRDD_FROM_GPR1_0_TO_VSR0;
+ l_opcode += (i_reg_num << 21);
+ }
+ else
+ {
+ l_opcode = OPCODE_MTVSRDD_FROM_GPR1_0_TO_VSR32;
+ l_opcode += ((i_reg_num - 32) << 21);
+ }
+
FAPI_TRY(ram_opcode(l_opcode, true));
}
+
+#endif
else
{
FAPI_ASSERT(false,
@@ -568,6 +900,26 @@ fapi2::ReturnCode RamCore::put_reg(const Enum_RegType i_type, const uint32_t i_r
"Type of reg is not supported");
}
+ //restore GPR0 if necessary
+ if(iv_write_gpr0 && !l_write_gpr0)
+ {
+ FAPI_TRY(fapi2::putScom(iv_target, C_SCR0, l_backup_gpr0));
+ l_opcode = OPCODE_MFSPR_FROM_SPRD_TO_GPR0;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+ }
+
+#ifndef __PPE__
+
+ //restore GPR1 if necessary
+ if(iv_write_gpr1 && (i_type == REG_VSR))
+ {
+ FAPI_TRY(fapi2::putScom(iv_target, C_SCR0, l_backup_gpr1));
+ l_opcode = OPCODE_MFSPR_FROM_SPRD_TO_GPR1;
+ FAPI_TRY(ram_opcode(l_opcode, true));
+ }
+
+#endif
+
// ram_cleanup
if(!i_allow_mult)
{
@@ -575,7 +927,18 @@ fapi2::ReturnCode RamCore::put_reg(const Enum_RegType i_type, const uint32_t i_r
}
fapi_try_exit:
- FAPI_INF("Exiting put register");
- return fapi2::current_err;
+ // Error happened and it's not ram error, call ram_cleanup to restore the backup registers
+ // If it is ram error, do not call ram_cleanup, so that no new ramming will be executed
+ // Do not use "FAPI_TRY" to avoid endless loop
+ fapi2::ReturnCode first_err = fapi2::current_err;
+
+ if((fapi2::current_err != fapi2::FAPI2_RC_SUCCESS) && !iv_ram_err && iv_ram_setup)
+ {
+ ram_cleanup();
+ }
+
+ FAPI_DBG("Exiting put register");
+ return first_err;
}
+
OpenPOWER on IntegriCloud