diff options
author | LiuYangFan <shliuyf@cn.ibm.com> | 2016-04-01 03:25:41 -0500 |
---|---|---|
committer | Prachi Gupta <pragupta@us.ibm.com> | 2016-06-08 11:45:52 -0500 |
commit | 257861dcd4b5a7cce8b09c936ec26f8a9d36bc37 (patch) | |
tree | d3d7633bc84198b730a5bd79232b4604662ba7e1 /import/chips/p9 | |
parent | 1627cdfd0eb31b7d77c90a24cd7d4d0496242f11 (diff) | |
download | talos-sbe-257861dcd4b5a7cce8b09c936ec26f8a9d36bc37.tar.gz talos-sbe-257861dcd4b5a7cce8b09c936ec26f8a9d36bc37.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/22747
Reviewed-by: Sachin Gupta <sgupta2m@in.ibm.com>
Diffstat (limited to 'import/chips/p9')
-rw-r--r-- | import/chips/p9/procedures/hwp/perv/p9_ram_core.C | 647 | ||||
-rw-r--r-- | import/chips/p9/procedures/hwp/perv/p9_ram_core.H | 14 | ||||
-rw-r--r-- | import/chips/p9/procedures/xml/error_info/p9_ram_errors.xml | 17 |
3 files changed, 521 insertions, 157 deletions
diff --git a/import/chips/p9/procedures/hwp/perv/p9_ram_core.C b/import/chips/p9/procedures/hwp/perv/p9_ram_core.C index 6553c03f..b31b73ef 100644 --- a/import/chips/p9/procedures/hwp/perv/p9_ram_core.C +++ b/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; } + diff --git a/import/chips/p9/procedures/hwp/perv/p9_ram_core.H b/import/chips/p9/procedures/hwp/perv/p9_ram_core.H index 1e2d9d11..2384bc8b 100644 --- a/import/chips/p9/procedures/hwp/perv/p9_ram_core.H +++ b/import/chips/p9/procedures/hwp/perv/p9_ram_core.H @@ -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 @@ -132,11 +132,13 @@ class RamCore private: fapi2::Target<fapi2::TARGET_TYPE_CORE> iv_target; // core target - uint8_t iv_thread; // thread number - bool iv_ram_enable; // ram mode is enabled - bool iv_ram_setup; // ram mode is enabled and register backup is done - bool iv_write_gpr0; // putGPR0 operation is executed - bool iv_write_gpr1; // putGPR1 operatoin is executed + uint8_t iv_thread; // thread number + bool iv_ram_enable; // ram mode is enabled + bool iv_ram_scr0_save; // SCR0 is saved when setup + bool iv_ram_setup; // ram mode is enabled and register backup is done + bool iv_ram_err; // error happened during ram + bool iv_write_gpr0; // putGPR0 operation is executed + bool iv_write_gpr1; // putGPR1 operatoin is executed fapi2::buffer<uint64_t> iv_backup_buf0; // register backup data fapi2::buffer<uint64_t> iv_backup_buf1; // register backup data fapi2::buffer<uint64_t> iv_backup_buf2; // register backup data diff --git a/import/chips/p9/procedures/xml/error_info/p9_ram_errors.xml b/import/chips/p9/procedures/xml/error_info/p9_ram_errors.xml index eeb58521..2ad7d24a 100644 --- a/import/chips/p9/procedures/xml/error_info/p9_ram_errors.xml +++ b/import/chips/p9/procedures/xml/error_info/p9_ram_errors.xml @@ -31,12 +31,11 @@ </hwpError> <!-- ******************************************************************** --> <hwpError> - <rc>RC_P9_SPR_INVALID_RW_MODE_ACCESS_ERR</rc> + <rc>RC_P9_SPR_NAME_MAP_ACCESS_ERR</rc> <description> - Illegal SPR read/write mode access + Illegal SPR name or read/write mode access </description> <ffdc>REGNAME</ffdc> - <ffdc>RWFLAG</ffdc> <callout> <procedure>CODE</procedure> <priority>MEDIUM</priority> @@ -44,22 +43,22 @@ </hwpError> <!-- ******************************************************************** --> <hwpError> - <rc>RC_P9_SPR_INVALID_NAME_ACCESS_ERR</rc> + <rc>RC_P9_RAM_NOT_SETUP_ERR</rc> <description> - Illegal SPR name access + RAM is not setup as active before doing ram or cleanup </description> - <ffdc>REGNAME</ffdc> <callout> <procedure>CODE</procedure> - <priority>MEDIUM</priority> + <priority>HIGH</priority> </callout> </hwpError> <!-- ******************************************************************** --> <hwpError> - <rc>RC_P9_RAM_NOT_SETUP_ERR</rc> + <rc>RC_P9_RAM_THREAD_NOT_STOP_ERR</rc> <description> - RAM is not setup as active before doing ram or cleanup + The thread to perform ramming is not stopped </description> + <ffdc>THREAD</ffdc> <callout> <procedure>CODE</procedure> <priority>HIGH</priority> |