diff options
author | Greg Still <stillgs@us.ibm.com> | 2016-04-22 07:10:46 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2016-06-10 15:12:29 -0400 |
commit | 3b98533e96b051b911f1e9b4715d77166434a2bf (patch) | |
tree | d34d369c624f304d4544ed5d7ad2900e81259388 /src/import/chips/p9/procedures/hwp | |
parent | d1b7166669d696f57ce8ceb3f67c25bdb9ff7446 (diff) | |
download | talos-hostboot-3b98533e96b051b911f1e9b4715d77166434a2bf.tar.gz talos-hostboot-3b98533e96b051b911f1e9b4715d77166434a2bf.zip |
p9_pm_occ_control Fix OCC memory boot launching
- Build and push launcher instructions into OCC SRAM
- Set SRAM Boot Vector 3 (FFFF_FFFC) to branch to launcher
- Per OCC team, offset is HOMER+0x40
Change-Id: If5c7abaed5c0f04f63f47e9eb245465e747aa075
Original-Change-Id: I2abbfea8de7b18d6010ee336031d0867cf9f0e99
RTC: 150818
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/23561
Tested-by: Jenkins Server
Tested-by: PPE CI
Tested-by: Hostboot CI
Reviewed-by: William A. Bryan <wilbryan@us.ibm.com>
Reviewed-by: Sangeetha T S <sangeet2@in.ibm.com>
Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/25641
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9/procedures/hwp')
3 files changed, 215 insertions, 6 deletions
diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_pm_occ_control.C b/src/import/chips/p9/procedures/hwp/pm/p9_pm_occ_control.C index e1ab713d6..b4f203e08 100644 --- a/src/import/chips/p9/procedures/hwp/pm/p9_pm_occ_control.C +++ b/src/import/chips/p9/procedures/hwp/pm/p9_pm_occ_control.C @@ -29,7 +29,211 @@ // ----------------------------------------------------------------------------- // Includes // ----------------------------------------------------------------------------- +#include <p9_pm.H> #include <p9_pm_occ_control.H> +#include <p9_pm_ocb_indir_setup_circular.H> +#include <p9_pm_ocb_indir_setup_linear.H> +#include <p9_pm_ocb_indir_access.H> +#include <p9_pm_utils.H> + +/** + * @brief enumerates opcodes for few instructions. + */ +enum +{ + ORI_OPCODE = 24, + ORIS_OPCODE = 25, + LIS_OPCODE = 15, + BR_OPCODE = 18, + BCCTR_OPCODE = 19, + OPCODE_31 = 31, + MTSPR_CONST1 = 467, + BCCTR_CONST1 = 528, + CTR = 9, + OCC_BOOT_OFFSET = 0x40, + OCC_SRAM_BOOT_ADDR = 0xFFF40000, + OCC_MEM_BOOT_PGMADDR = 0xFFF40000, +}; + +//----------------------------------------------------------------------------- + +/** + * @brief generates ori instruction code. + * @param[in] i_Rs Source register number + * @param[in] i_Ra Destination regiser number + * @param[in] i_data 16 bit immediate data + * @return returns 32 bit instruction representing ori instruction. + */ +uint32_t ppc_ori( const uint16_t i_Rs, const uint16_t i_Ra, + const uint16_t i_data ) +{ + uint32_t oriInstOpcode = 0; + oriInstOpcode = ORI_OPCODE << (31 - 5); + oriInstOpcode |= i_Rs << (31 - 10); + oriInstOpcode |= i_Ra << (31 - 15); + oriInstOpcode |= i_data; + + return oriInstOpcode; +} + + +//----------------------------------------------------------------------------- + +/** + * @brief generates lis (eg addis to 0) instruction code. + * @param[in] i_Rt Target register number + * @param[in] i_data 16 bit immediate data + * @return returns 32 bit instruction representing lis instruction. + */ +uint32_t ppc_lis( const uint16_t i_Rt, + const uint16_t i_data ) +{ + uint32_t lisInstOpcode = 0; + lisInstOpcode = LIS_OPCODE << (31 - 5); + lisInstOpcode |= i_Rt << (31 - 10); + lisInstOpcode |= i_data; + + return lisInstOpcode; +} + + +//----------------------------------------------------------------------------- + +/** + * @brief generates branch absolute instruction code. + * @param[in] i_TargetAddr Target address + * @return returns 32 bit instruction representing branch absolute instruction. + */ +uint32_t ppc_b( const uint32_t i_TargetAddr) +{ + uint32_t brInstOpcode = 0; + brInstOpcode = BR_OPCODE << (31 - 5); + brInstOpcode |= (i_TargetAddr & 0x03FFFFFF); + + return brInstOpcode; +} + +//----------------------------------------------------------------------------- + +/** + * @brief generates branch conditional to count register instruction code. + * @return returns 32 bit instruction representing branch absolute instruction. + */ +uint32_t ppc_bctr( ) +{ + uint32_t bctrInstOpcode = 0; + bctrInstOpcode = BCCTR_OPCODE << (31 - 5); + bctrInstOpcode |= 20 << (31 - 10); // BO + // BI = 0 taken care by bctrInstOpcode = 0 + bctrInstOpcode |= BCCTR_CONST1 << 1; + + return bctrInstOpcode; +} + +//----------------------------------------------------------------------------- + +/** + * @brief generates instruction for mtspr + * @param[in] i_Rs source register number + * @param[in] i_Spr represents spr where data is to be moved. + * @return returns 32 bit instruction representing mtspr instruction. + */ +uint32_t ppc_mtspr( const uint16_t i_Rs, const uint16_t i_Spr ) +{ + uint32_t mtsprInstOpcode = 0; + mtsprInstOpcode = OPCODE_31 << (31 - 5); + uint32_t temp = (( i_Spr & 0x03FF ) << (31 - 20)); + mtsprInstOpcode |= ( temp & 0x0000F800 ) << 5; // Perform swizzle + mtsprInstOpcode |= ( temp & 0x001F0000 ) >> 5; // Perform swizzle + mtsprInstOpcode |= MTSPR_CONST1 << 1; + + return mtsprInstOpcode; +} + + +/** + * @brief Creates and loads the OCC memory boot launcher + * @param[in] i_target Chip target + * @return returns 32 bit instruction representing mtspr instruction. + */ +fapi2::ReturnCode bootMemory( + const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target) +{ + static const uint32_t SRAM_PROGRAM_SIZE = 2; // in double words + uint64_t l_sram_program[SRAM_PROGRAM_SIZE]; + fapi2::buffer<uint64_t> l_data64; + fapi2::ReturnCode l_rc; + uint32_t l_ocb_length_act = 0; + + // Setup use OCB channel 1 for placing instruction in SRAM + // Channel will be returned to Linear Stream, Circular upon exit + FAPI_EXEC_HWP(l_rc, p9_pm_ocb_indir_setup_linear, i_target, + p9ocb::OCB_CHAN1, + p9ocb::OCB_TYPE_LINSTR, + OCC_SRAM_BOOT_ADDR); // Bar + FAPI_TRY(l_rc); + + + // lis r1, 0x8000 + l_sram_program[0] = ((uint64_t)ppc_lis(1, 0x8000) << 32); + FAPI_DBG("ppc_lis: 0x%08X with data 0x%08X", + ppc_lis(1, 0x8000), 0x8000); + + // ori r1, r1, OCC_BOOT_OFFSET + l_sram_program[0] |= (ppc_ori(1, 1, OCC_BOOT_OFFSET)); + FAPI_DBG("ppc_ori: 0x%08X with data 0x%08X", + ppc_ori(1, 1, OCC_BOOT_OFFSET), OCC_BOOT_OFFSET); + + // mtctr (mtspr CTR, r1 ) + l_sram_program[1] = ((uint64_t)ppc_mtspr(CTR, 1) << 32); + FAPI_DBG("ppc_mtspr: 0x%08X with spr 0x%08X", + ppc_mtspr(CTR, 1), CTR); + + // bctr + l_sram_program[1] |= ppc_bctr(); + FAPI_DBG("ppc_bctr: 0x%08X", ppc_bctr()); + + FAPI_DBG("SRAM PGM[0]: 0x%016llX", l_sram_program[0]); + FAPI_DBG("SRAM PGM[1]: 0x%016llX", l_sram_program[1]); + + // Write to SRAM + FAPI_EXEC_HWP(l_rc, p9_pm_ocb_indir_access, i_target, + p9ocb::OCB_CHAN1, + p9ocb::OCB_PUT, + SRAM_PROGRAM_SIZE, + false, + 0, + l_ocb_length_act, + l_sram_program); + + FAPI_ASSERT(l_ocb_length_act == SRAM_PROGRAM_SIZE, + fapi2::OCC_CONTROL_MEM_BOOT_LENGTH_MISMATCH() + .set_ACTLENGTH(l_ocb_length_act) + .set_LENGTH(SRAM_PROGRAM_SIZE), + "OCC memory boot launcher length mismatch"); + + // b OCC_SRAM_BOOT_ADDR + l_data64.insertFromRight<0, 32>(ppc_b(OCC_SRAM_BOOT_ADDR)); + + // Write to SBV3 + FAPI_TRY(fapi2::putScom(i_target, PU_SRAM_SRBV3_SCOM, l_data64), + "SRAM Boot Vector 3"); + +fapi_try_exit: + // Channel 1 returned to Linear Stream, Circular upon exit + FAPI_EXEC_HWP(l_rc, p9_pm_ocb_indir_setup_circular, i_target, + p9ocb::OCB_CHAN1, + p9ocb::OCB_TYPE_NULL, + 0, // Bar + 0, // Length + p9ocb::OCB_Q_OUFLOW_NULL, + p9ocb::OCB_Q_ITPTYPE_NULL); + fapi2::current_err = l_rc; + + return fapi2::current_err; +} + + // ----------------------------------------------------------------------------- // Constant Defintions @@ -88,15 +292,17 @@ fapi2::ReturnCode p9_pm_occ_control FAPI_TRY(fapi2::putScom(i_target, PU_SRAM_SRBV1_SCOM, l_data64)); FAPI_TRY(fapi2::putScom(i_target, PU_SRAM_SRBV2_SCOM, l_data64)); - FAPI_DBG("Writing to Boot Vector 3 Register"); + if (i_ppc405_boot_ctrl == p9occ_ctrl::PPC405_BOOT_SRAM) { + FAPI_DBG("Writing to Boot Vector 3 Register"); l_data64.flush<0>().insertFromRight(PPC405_BRANCH_SRAM_INSTR, 0, 32); } else if (i_ppc405_boot_ctrl == p9occ_ctrl::PPC405_BOOT_MEM) { - l_data64.flush<0>().insertFromRight(PPC405_BRANCH_MEM_INSTR, 0, 32); + FAPI_INF("Setting up for memory boot"); + FAPI_TRY(bootMemory(i_target), , "Booting from Memory Failed"); } else { diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_pm_occ_control.H b/src/import/chips/p9/procedures/hwp/pm/p9_pm_occ_control.H index 22f3d74ff..03000890c 100644 --- a/src/import/chips/p9/procedures/hwp/pm/p9_pm_occ_control.H +++ b/src/import/chips/p9/procedures/hwp/pm/p9_pm_occ_control.H @@ -35,10 +35,12 @@ /// - Initialize SRBV0 per passed parameter (i_ppc405_boot_ctrl) /// - If (i_ppc405_boot_ctrl = PPC405_BOOT_SRAM) /// Initialize to Branch Absolute 0xFFF80010 -/// - If (i_ppc405_boot_ctrl = PPC405_BOOT_MEM) -/// Initialize to Branch Absolute 0x00000010 -/// - If (i_ppc405_boot_ctrl = PPC405_BOOT_OLD) +/// - Else If (i_ppc405_boot_ctrl = PPC405_BOOT_OLD) /// initialize to Branch Relative -16 +/// - Else (i_ppc405_boot_ctrl = PPC405_BOOT_MEM || NULL) +/// Load branch formation code into OCC SRAM at 0xFFF40000 +/// to branch to 0x80000010 (HOMER + 0x40) +/// Initialize to Branch Absolute 0xFFF40000 /// - Write PPC405 reset/halt bits based on i_ppc405_reset_ctrl (OCR, OJCFG) /// - if PPC405_RESET_NULL , do nothing /// - if PPC405_RESET_OFF , write reset bit to 0 (PPC405 not reset) diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_pm_occ_control.mk b/src/import/chips/p9/procedures/hwp/pm/p9_pm_occ_control.mk index f2274b2c2..4d056389b 100644 --- a/src/import/chips/p9/procedures/hwp/pm/p9_pm_occ_control.mk +++ b/src/import/chips/p9/procedures/hwp/pm/p9_pm_occ_control.mk @@ -7,7 +7,7 @@ # # EKB Project # -# COPYRIGHT 2015 +# COPYRIGHT 2015,2016 # [+] International Business Machines Corp. # # @@ -17,4 +17,5 @@ # # IBM_PROLOG_END_TAG PROCEDURE=p9_pm_occ_control +$(call ADD_MODULE_INCDIR,$(PROCEDURE),$(ROOTPATH)/chips/p9/procedures/hwp/lib/) $(call BUILD_PROCEDURE) |