diff options
author | Thi Tran <thi@us.ibm.com> | 2015-08-03 10:55:38 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2015-08-24 15:57:56 -0500 |
commit | 1a26c51cfab6d6c3cae063fd51d13d48d4254224 (patch) | |
tree | d257cb2fea6653bc0512f626f43176ea4a7caecf | |
parent | 3d6217acec3cc424dc631b39b61e8e0eac8406ed (diff) | |
download | talos-hostboot-1a26c51cfab6d6c3cae063fd51d13d48d4254224.tar.gz talos-hostboot-1a26c51cfab6d6c3cae063fd51d13d48d4254224.zip |
SW310621: INITPROC: FSP&Hostboot - secure boot updates -- A/PCI/DMI PLL scannin
CQ:SW310621
Change-Id: I6532e138dcbf45bf6148bfb2f7dc8134dcfbb7e5
Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/19404/
Reviewed-by: Thi N. Tran <thi@us.ibm.com>
Tested-by: Thi N. Tran <thi@us.ibm.com>
Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/19453
Reviewed-by: PRACHI GUPTA <pragupta@us.ibm.com>
Tested-by: Jenkins OP Build CI
Tested-by: Jenkins OP HW
Tested-by: FSP CI Jenkins
Tested-by: Jenkins Server
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
29 files changed, 2467 insertions, 1165 deletions
diff --git a/src/include/usr/isteps/istep06list.H b/src/include/usr/isteps/istep06list.H index a1e198a04..8b55f23a0 100644 --- a/src/include/usr/isteps/istep06list.H +++ b/src/include/usr/isteps/istep06list.H @@ -160,6 +160,8 @@ const DepModInfo g_istep06Dependancies = { DEP_LIB(libsbe.so), DEP_LIB(libporeve.so), DEP_LIB(libpstates.so), + DEP_LIB(libcore_activate.so), + DEP_LIB(libsecure_boot.so), NULL } }; diff --git a/src/include/usr/isteps/istep07list.H b/src/include/usr/isteps/istep07list.H index d230bd25e..46cefeaa8 100644 --- a/src/include/usr/isteps/istep07list.H +++ b/src/include/usr/isteps/istep07list.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2012,2014 */ +/* Contributors Listed Below - COPYRIGHT 2012,2015 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -122,6 +122,7 @@ const DepModInfo g_istep07Dependancies = { { DEP_LIB(libnest_chiplets.so), DEP_LIB(libslave_sbe.so), + DEP_LIB(libsecure_boot.so), NULL } }; diff --git a/src/include/usr/isteps/istep08list.H b/src/include/usr/isteps/istep08list.H index 698b9c7db..247fb4801 100644 --- a/src/include/usr/isteps/istep08list.H +++ b/src/include/usr/isteps/istep08list.H @@ -5,7 +5,9 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012,2014 */ +/* Contributors Listed Below - COPYRIGHT 2012,2015 */ +/* [+] International Business Machines Corp. */ +/* */ /* */ /* Licensed under the Apache License, Version 2.0 (the "License"); */ /* you may not use this file except in compliance with the License. */ @@ -116,6 +118,7 @@ const DepModInfo g_istep08Dependancies = { DEP_LIB(libedi_ei_initialization.so), DEP_LIB(libdmi_training.so), DEP_LIB(libnest_chiplets.so), + DEP_LIB(libsecure_boot.so), NULL } }; diff --git a/src/include/usr/isteps/istep11list.H b/src/include/usr/isteps/istep11list.H index 7006c83c2..2b4895323 100644 --- a/src/include/usr/isteps/istep11list.H +++ b/src/include/usr/isteps/istep11list.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2012,2014 */ +/* Contributors Listed Below - COPYRIGHT 2012,2015 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -159,6 +159,8 @@ const DepModInfo g_istep11Dependancies = { DEP_LIB(libdmi_training.so), DEP_LIB(libedi_ei_initialization.so), DEP_LIB(libnest_chiplets.so), + DEP_LIB(libsecure_boot.so), + DEP_LIB(libslave_sbe.so), #endif NULL } diff --git a/src/makefile b/src/makefile index 84f4a9c44..87c20d06b 100644 --- a/src/makefile +++ b/src/makefile @@ -168,6 +168,7 @@ EXTENDED_MODULES += $(if $(CONFIG_GPIODD),gpio,) EXTENDED_MODULES += $(if $(CONFIG_CONSOLE),console) EXTENDED_MODULES += $(if $(CONFIG_CONSOLE_OUTPUT_ERRORDISPLAY),errldisplay) EXTENDED_MODULES += $(if $(CONFIG_BMC_IPMI),ipmi) +EXTENDED_MODULES += secure_boot TESTCASE_MODULES += cxxtest TESTCASE_MODULES += testtrace diff --git a/src/usr/hwpf/hwp/bus_training/io_dccal.C b/src/usr/hwpf/hwp/bus_training/io_dccal.C index dc3b0fb45..217774888 100644 --- a/src/usr/hwpf/hwp/bus_training/io_dccal.C +++ b/src/usr/hwpf/hwp/bus_training/io_dccal.C @@ -22,7 +22,7 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: io_dccal.C,v 1.39 2014/12/02 00:17:33 szhong Exp $ +// $Id: io_dccal.C,v 1.40 2015/05/14 21:03:34 jmcgill Exp $ // *!*************************************************************************** // *! (C) Copyright International Business Machines Corp. 1997, 1998 // *! All Rights Reserved -- Property of IBM @@ -766,15 +766,8 @@ ReturnCode io_dccal(const Target& target){ io_interface_t master_interface=CP_IOMC0_P0; uint32_t master_group=0; - fapi::ATTR_PROC_PB_BNDY_DMIPLL_DATA_Type pb_bndy_dmipll_data={0}; - fapi::ATTR_PROC_AB_BNDY_PLL_DATA_Type ab_bndy_pll_data={0}; - fapi::ATTR_MEMB_TP_BNDY_PLL_DATA_Type tp_bndy_pll_data={0}; - ecmdDataBufferBase ring_data; fapi::Target parent_target; - uint32_t ring_length=0; - uint32_t rc_ecmd=0; - -const fapi::Target& TARGET = target; + const fapi::Target& TARGET = target; FAPI_DBG("Running IO DCCAL PROCEDURE"); // This is a DMI/MC bus @@ -784,36 +777,7 @@ const fapi::Target& TARGET = target; master_interface=CP_IOMC0_P0; // base scom for MC bus master_group=3; // Design requires us to do this as per scom map and layout - // obtain parent chip target needed for ring manipulation - rc = fapiGetParentChip(target, parent_target); - if (rc) - { - FAPI_ERR("Error from fapiGetParentChip"); - return(rc); - } - - // install PLL config for dccal operation - rc = FAPI_ATTR_GET(ATTR_PROC_PB_BNDY_DMIPLL_LENGTH, &parent_target, ring_length); // -- get length of scan ring - if (rc) - { - FAPI_ERR("Error from FAPI_ATTR_GET (ATTR_PROC_PB_BNDY_DMIPLL_LENGTH)"); - return(rc); - } - rc = FAPI_ATTR_GET(ATTR_PROC_PB_BNDY_DMIPLL_DATA, &parent_target, pb_bndy_dmipll_data); // -- get scan ring data - if (rc) - { - FAPI_ERR("Error from FAPI_ATTR_GET (ATTR_PROC_PB_BNDY_DMIPLL_DATA)"); - return(rc); - } - - rc_ecmd |= ring_data.setBitLength(ring_length); - rc_ecmd |= ring_data.insert(pb_bndy_dmipll_data, 0, ring_length, 0); // -- put data into ecmd buffer - if (rc_ecmd) - { - rc.setEcmdError(rc_ecmd); - return(rc); - } - + // determine chip unit position uint8_t mcs_pos; rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &target, mcs_pos); if (rc) @@ -822,26 +786,19 @@ const fapi::Target& TARGET = target; return(rc); } - uint32_t refclksel_offsets[8]; - rc = FAPI_ATTR_GET(ATTR_PROC_DMI_CUPLL_REFCLKSEL_OFFSET, &parent_target, refclksel_offsets); + // obtain parent chip target needed for ring manipulation + rc = fapiGetParentChip(target, parent_target); if (rc) { - FAPI_ERR("Error from FAPI_ATTR_GET (ATTR_PROC_DMI_CUPLL_REFCLKSEL_OFFSET)"); - return(rc); - } - - rc_ecmd |= ring_data.setBit(refclksel_offsets[mcs_pos]); - if (rc_ecmd) - { - rc.setEcmdError(rc_ecmd); + FAPI_ERR("Error from fapiGetParentChip"); return(rc); } - // update PLL + // update PLL for dccal operation rc = proc_a_x_pci_dmi_pll_scan_bndy(parent_target, - NEST_CHIPLET_0x02000000, - PB_BNDY_DMIPLL_RING_ADDR, - ring_data, + RING_ADDRESS_PROC_PB_BNDY_DMIPLL, + RING_OP_MOD_REFCLK_SEL, + static_cast<p8_pll_utils_bus_id>(mcs_pos), true); if (rc) { @@ -866,22 +823,10 @@ const fapi::Target& TARGET = target; } // restore PLL config for functional operation - rc = FAPI_ATTR_GET(ATTR_PROC_PB_BNDY_DMIPLL_DATA, &parent_target, pb_bndy_dmipll_data); // -- get scan ring data - if (rc) - { - FAPI_ERR("Error from FAPI_ATTR_GET (ATTR_PROC_PB_BNDY_DMIPLL_DATA)"); - return(rc); - } - rc_ecmd |= ring_data.insert(pb_bndy_dmipll_data, 0, ring_length, 0); // -- put data into ecmd buffer - if (rc_ecmd) - { - rc.setEcmdError(rc_ecmd); - return(rc); - } rc = proc_a_x_pci_dmi_pll_scan_bndy(parent_target, - NEST_CHIPLET_0x02000000, - PB_BNDY_DMIPLL_RING_ADDR, - ring_data, + RING_ADDRESS_PROC_PB_BNDY_DMIPLL, + RING_OP_MOD_REFCLK_SEL, + static_cast<p8_pll_utils_bus_id>(mcs_pos), true); if (rc) { @@ -896,46 +841,10 @@ const fapi::Target& TARGET = target; master_group=0; // install PLL config for dccal operation - rc = FAPI_ATTR_GET(ATTR_MEMB_TP_BNDY_PLL_LENGTH, &target, ring_length); // -- get length of scan ring - if (rc) - { - FAPI_ERR("Error from FAPI_ATTR_GET (ATTR_MEMB_TP_BNDY_PLL_LENGTH)"); - return(rc); - } - rc = FAPI_ATTR_GET(ATTR_MEMB_TP_BNDY_PLL_DATA, &target, tp_bndy_pll_data); // -- get scan ring data - if (rc) - { - FAPI_ERR("Error from FAPI_ATTR_GET (ATTR_MEMB_TP_BNDY_PLL_DATA)"); - return(rc); - } - rc_ecmd |= ring_data.setBitLength(ring_length); - rc_ecmd |= ring_data.insert(tp_bndy_pll_data, 0, ring_length, 0); // -- put data into ecmd buffer - if (rc_ecmd) - { - rc.setEcmdError(rc_ecmd); - return(rc); - } - - uint32_t refclksel_offset; - rc = FAPI_ATTR_GET(ATTR_MEMB_DMI_CUPLL_REFCLKSEL_OFFSET, &target, refclksel_offset); - if (rc) - { - FAPI_ERR("Error from FAPI_ATTR_GET (ATTR_MEMB_DMI_CUPLL_REFCLKSEL_OFFSET)"); - return(rc); - } - - rc_ecmd |= ring_data.setBit(refclksel_offset); - if (rc_ecmd) - { - rc.setEcmdError(rc_ecmd); - return(rc); - } - - // update PLL rc = proc_a_x_pci_dmi_pll_scan_bndy(target, - TP_CHIPLET_0x01000000, - MEMB_TP_BNDY_PLL_RING_ADDR, - ring_data, + RING_ADDRESS_MEMB_TP_BNDY_PLL, + RING_OP_MOD_REFCLK_SEL, + RING_BUS_ID_0, true); if (rc) { @@ -960,23 +869,10 @@ const fapi::Target& TARGET = target; } // restore PLL config for functional operation - rc = FAPI_ATTR_GET(ATTR_MEMB_TP_BNDY_PLL_DATA, &target, tp_bndy_pll_data); // -- get scan ring data - if (rc) - { - FAPI_ERR("Error from FAPI_ATTR_GET (ATTR_MEMB_TP_BNDY_PLL_DATA)"); - return(rc); - } - rc_ecmd |= ring_data.insert(tp_bndy_pll_data, 0, ring_length, 0); // -- put data into ecmd buffer - if (rc_ecmd) - { - rc.setEcmdError(rc_ecmd); - return(rc); - } - rc = proc_a_x_pci_dmi_pll_scan_bndy(target, - TP_CHIPLET_0x01000000, - MEMB_TP_BNDY_PLL_RING_ADDR, - ring_data, + RING_ADDRESS_MEMB_TP_BNDY_PLL, + RING_OP_MOD_REFCLK_SEL, + RING_BUS_ID_0, true); if (rc) { @@ -996,35 +892,6 @@ const fapi::Target& TARGET = target; master_interface=CP_FABRIC_A0; // base scom for A bus , assume translation to A1 by PLAT master_group=0; // Design requires us to do this as per scom map and layout - // obtain parent chip target needed for ring manipulation - rc = fapiGetParentChip(target, parent_target); - if (rc) - { - FAPI_ERR("Error from fapiGetParentChip"); - return(rc); - } - - // install PLL config for dccal operation - rc = FAPI_ATTR_GET(ATTR_PROC_AB_BNDY_PLL_LENGTH, &parent_target, ring_length); // -- get length of scan ring - if (rc) - { - FAPI_ERR("Error from FAPI_ATTR_GET (ATTR_PROC_AB_BNDY_PLL_LENGTH)"); - return(rc); - } - rc = FAPI_ATTR_GET(ATTR_PROC_AB_BNDY_PLL_DATA, &parent_target, ab_bndy_pll_data); // -- get scan ring data - if (rc) - { - FAPI_ERR("Error from FAPI_ATTR_GET (ATTR_PROC_AB_BNDY_PLL_DATA)"); - return(rc); - } - rc_ecmd |= ring_data.setBitLength(ring_length); - rc_ecmd |= ring_data.insert(ab_bndy_pll_data, 0, ring_length, 0); // -- put data into ecmd buffer - if (rc_ecmd) - { - rc.setEcmdError(rc_ecmd); - return(rc); - } - uint8_t abus; rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &target, abus); if (rc) @@ -1033,26 +900,19 @@ const fapi::Target& TARGET = target; return(rc); } - uint32_t refclksel_offsets[3]; - rc = FAPI_ATTR_GET(ATTR_PROC_ABUS_CUPLL_REFCLKSEL_OFFSET, &parent_target, refclksel_offsets); + // obtain parent chip target needed for ring manipulation + rc = fapiGetParentChip(target, parent_target); if (rc) { - FAPI_ERR("Error from FAPI_ATTR_GET (ATTR_PROC_ABUS_CUPLL_REFCLKSEL_OFFSET)"); - return(rc); - } - - rc_ecmd |= ring_data.setBit(refclksel_offsets[abus]); - if (rc_ecmd) - { - rc.setEcmdError(rc_ecmd); + FAPI_ERR("Error from fapiGetParentChip"); return(rc); } - // update PLL + // install PLL config for dccal operation rc = proc_a_x_pci_dmi_pll_scan_bndy(parent_target, - A_BUS_CHIPLET_0x08000000, - AB_BNDY_PLL_RING_ADDR, - ring_data, + RING_ADDRESS_PROC_AB_BNDY_PLL, + RING_OP_MOD_REFCLK_SEL, + static_cast<p8_pll_utils_bus_id>(abus), true); if (rc) { @@ -1075,23 +935,10 @@ const fapi::Target& TARGET = target; } // restore PLL config for functional operation - rc = FAPI_ATTR_GET(ATTR_PROC_AB_BNDY_PLL_DATA, &parent_target, ab_bndy_pll_data); // -- get scan ring data - if (rc) - { - FAPI_ERR("Error from FAPI_ATTR_GET (ATTR_PROC_AB_BNDY_PLL_DATA)"); - return(rc); - } - rc_ecmd |= ring_data.setBitLength(ring_length); - rc_ecmd |= ring_data.insert(ab_bndy_pll_data, 0, ring_length, 0); // -- put data into ecmd buffer - if (rc_ecmd) - { - rc.setEcmdError(rc_ecmd); - return(rc); - } rc = proc_a_x_pci_dmi_pll_scan_bndy(parent_target, - A_BUS_CHIPLET_0x08000000, - AB_BNDY_PLL_RING_ADDR, - ring_data, + RING_ADDRESS_PROC_AB_BNDY_PLL, + RING_OP_MOD_REFCLK_SEL, + static_cast<p8_pll_utils_bus_id>(abus), true); if (rc) { diff --git a/src/usr/hwpf/hwp/bus_training/io_run_training.C b/src/usr/hwpf/hwp/bus_training/io_run_training.C index 3ef49cfb1..8366c1bc4 100644 --- a/src/usr/hwpf/hwp/bus_training/io_run_training.C +++ b/src/usr/hwpf/hwp/bus_training/io_run_training.C @@ -22,7 +22,7 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: io_run_training.C,v 1.65 2014/12/04 02:01:55 thi Exp $ +// $Id: io_run_training.C,v 1.66 2015/05/14 21:03:37 jmcgill Exp $ // *!*************************************************************************** // *! (C) Copyright International Business Machines Corp. 1997, 1998 // *! All Rights Reserved -- Property of IBM @@ -60,19 +60,7 @@ extern "C" { ReturnCode io_training_set_pll_post_wiretest(const Target& target){ ReturnCode rc; - fapi::ATTR_PROC_PB_BNDY_DMIPLL_DATA_Type pb_bndy_dmipll_data={0}; - fapi::ATTR_PROC_AB_BNDY_PLL_DATA_Type ab_bndy_pll_data={0}; - fapi::ATTR_MEMB_TP_BNDY_PLL_DATA_Type tp_bndy_pll_data={0}; - - // For the PLL Partial updation logic we need PFD360 offsets into the Ring now - uint32_t proc_dmi_cupll_pfd360_offset[8]; - uint32_t memb_dmi_cupll_pfd360_offset; - uint32_t proc_abus_cupll_pfd360_offset[3]; - - ecmdDataBufferBase ring_data; fapi::Target parent_target; - uint32_t ring_length=0; - uint32_t rc_ecmd=0; uint8_t chip_unit = 0; FAPI_DBG("Running PLL updation code"); @@ -84,7 +72,7 @@ extern "C" { { FAPI_DBG("This is a Processor DMI bus using base DMI scom address"); - // Lets get chip unit pos , used for PLL table lookup + // Lets get chip unit pos , used for PLL table lookup rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &target, chip_unit); @@ -103,54 +91,12 @@ extern "C" { return(rc); } - // install PLL config - rc = FAPI_ATTR_GET(ATTR_PROC_PB_BNDY_DMIPLL_LENGTH, &parent_target, ring_length); // -- get length of scan ring - if (rc) - { - FAPI_ERR("Error from FAPI_ATTR_GET (ATTR_PROC_PB_BNDY_DMIPLL_LENGTH)"); - return(rc); - } - rc = FAPI_ATTR_GET(ATTR_PROC_PB_BNDY_DMIPLL_DATA, &parent_target, pb_bndy_dmipll_data); // -- get scan ring data - if (rc) - { - FAPI_ERR("Error from FAPI_ATTR_GET (ATTR_PROC_PB_BNDY_DMIPLL_DATA)"); - return(rc); - } - - // Now we need the partial offset data also . First let us get PFD360 offsets - rc = FAPI_ATTR_GET(ATTR_PROC_DMI_CUPLL_PFD360_OFFSET, &parent_target, proc_dmi_cupll_pfd360_offset); - if (rc) - { - FAPI_ERR("Error fetching PFD360 offsets on MCS"); - return(rc); - } - - rc_ecmd |= ring_data.setBitLength(ring_length); - if (rc_ecmd) - { - rc.setEcmdError(rc_ecmd); - return(rc); - } - - rc =fapiGetRing(parent_target,PB_BNDY_DMIPLL_RING_ADDR ,ring_data,RING_MODE_SET_PULSE); - if (rc) - { - FAPI_ERR("Error performing GetRing operation on PB_BNDY_DMIPLL"); - return(rc); - } - FAPI_DBG("PFD bit to be cleared for DMI unit %d is %d",chip_unit,proc_dmi_cupll_pfd360_offset[chip_unit]); - rc_ecmd |= ring_data.clearBit(proc_dmi_cupll_pfd360_offset[chip_unit]); - // Now - if (rc_ecmd) - { - rc.setEcmdError(rc_ecmd); - return(rc); - } + // install PLL config (adjust PFD360) rc = proc_a_x_pci_dmi_pll_scan_bndy(parent_target, - NEST_CHIPLET_0x02000000, - PB_BNDY_DMIPLL_RING_ADDR, - ring_data, - true); + RING_ADDRESS_PROC_PB_BNDY_DMIPLL, + RING_OP_MOD_PFD360, + static_cast<p8_pll_utils_bus_id>(chip_unit), + true); if (rc) { FAPI_ERR("Error from proc_a_x_pci_dmi_pll_scan_bndy"); @@ -163,59 +109,12 @@ extern "C" { { FAPI_DBG("This is a Centaur DMI bus using base DMI scom address"); - // install PLL config - rc = FAPI_ATTR_GET(ATTR_MEMB_TP_BNDY_PLL_LENGTH, &target, ring_length); // -- get length of scan ring - if (rc) - { - FAPI_ERR("Error from FAPI_ATTR_GET (ATTR_MEMB_TP_BNDY_PLL_LENGTH)"); - return(rc); - } - rc = FAPI_ATTR_GET(ATTR_MEMB_TP_BNDY_PLL_DATA, &target, tp_bndy_pll_data); // -- get scan ring data - if (rc) - { - FAPI_ERR("Error from FAPI_ATTR_GET (ATTR_MEMB_TP_BNDY_PLL_DATA)"); - return(rc); - } - - // Now we need the partial offset data also . First let us get PFD360 offsets - rc = FAPI_ATTR_GET(ATTR_MEMB_DMI_CUPLL_PFD360_OFFSET, &target, memb_dmi_cupll_pfd360_offset); - if (rc) - { - FAPI_ERR("Error fetching PFD360 offsets on Centaur"); - return(rc); - } - - FAPI_DBG("Centaur PFD offset = %d",memb_dmi_cupll_pfd360_offset); - - FAPI_DBG("Ring length is %d",ring_length); - rc_ecmd |= ring_data.setBitLength(ring_length); - if (rc_ecmd) - { - rc.setEcmdError(rc_ecmd); - return(rc); - } - - rc=fapiGetRing(target,MEMB_TP_BNDY_PLL_RING_ADDR ,ring_data,RING_MODE_SET_PULSE); - if (rc) - { - FAPI_ERR("Get ring error on MEMB "); - return(rc); - } - // rc_ecmd |= ring_data.insert(pb_bndy_dmipll_data, 0, ring_length, 0); // -- put data into ecmd buffer - FAPI_DBG("PFD bit to be cleared for centaur is %d",memb_dmi_cupll_pfd360_offset); - rc_ecmd |=ring_data.clearBit(memb_dmi_cupll_pfd360_offset); - - //rc_ecmd |= ring_data.insert(tp_bndy_pll_data, 0, ring_length, 0); // -- put data into ecmd buffer - if (rc_ecmd) - { - rc.setEcmdError(rc_ecmd); - return(rc); - } + // install PLL config (adjust PFD360) rc = proc_a_x_pci_dmi_pll_scan_bndy(target, - TP_CHIPLET_0x01000000, - MEMB_TP_BNDY_PLL_RING_ADDR, - ring_data, - true); + RING_ADDRESS_MEMB_TP_BNDY_PLL, + RING_OP_MOD_PFD360, + RING_BUS_ID_0, + true); if (rc) { FAPI_ERR("Error from proc_a_x_pci_dmi_pll_scan_bndy"); @@ -253,54 +152,12 @@ extern "C" { return(rc); } - // install PLL config - rc = FAPI_ATTR_GET(ATTR_PROC_AB_BNDY_PLL_LENGTH, &parent_target, ring_length); // -- get length of scan ring - if (rc) - { - FAPI_ERR("Error from FAPI_ATTR_GET (ATTR_PROC_AB_BNDY_PLL_LENGTH)"); - return(rc); - } - rc = FAPI_ATTR_GET(ATTR_PROC_AB_BNDY_PLL_DATA, &parent_target, ab_bndy_pll_data); // -- get scan ring data - if (rc) - { - FAPI_ERR("Error from FAPI_ATTR_GET (ATTR_PROC_AB_BNDY_PLL_DATA)"); - return(rc); - } - - - // Now we need the partial offset data also . First let us get PFD360 offsets - rc = FAPI_ATTR_GET(ATTR_PROC_ABUS_CUPLL_PFD360_OFFSET, &parent_target, proc_abus_cupll_pfd360_offset); - if (rc) - { - FAPI_ERR("Error fetching PFD360 offsets on Abus"); - return(rc); - } - - rc_ecmd |= ring_data.setBitLength(ring_length); - if (rc_ecmd) - { - rc.setEcmdError(rc_ecmd); - return(rc); - } - rc =fapiGetRing(parent_target,AB_BNDY_PLL_RING_ADDR ,ring_data,RING_MODE_SET_PULSE); - if (rc) - { - FAPI_ERR("GetRing error on AB ring"); - return(rc); - } - FAPI_DBG("PFD bit to be cleared for Abus number %d is %d",chip_unit,proc_abus_cupll_pfd360_offset[chip_unit]); - rc_ecmd|=ring_data.clearBit(proc_abus_cupll_pfd360_offset[chip_unit]); - - if (rc_ecmd) - { - rc.setEcmdError(rc_ecmd); - return(rc); - } + // install PLL config (adjust PFD360) rc = proc_a_x_pci_dmi_pll_scan_bndy(parent_target, - A_BUS_CHIPLET_0x08000000, - AB_BNDY_PLL_RING_ADDR, - ring_data, - true); + RING_ADDRESS_PROC_AB_BNDY_PLL, + RING_OP_MOD_PFD360, + static_cast<p8_pll_utils_bus_id>(chip_unit), + true); if (rc) { FAPI_ERR("Error from proc_a_x_pci_dmi_pll_scan_bndy"); @@ -1118,6 +975,7 @@ extern "C" { FAPI_DBG("PLL SETTING FAILED ON MASTER SIDE "); return rc; } + // FAPI_DBG("Waiting for 1s after PLL Update on master"); // rc=fapiDelay(1000000,1000); // Run DE Now - as per Gary diff --git a/src/usr/hwpf/hwp/makefile b/src/usr/hwpf/hwp/makefile index 163bb529d..9a78c0d9a 100644 --- a/src/usr/hwpf/hwp/makefile +++ b/src/usr/hwpf/hwp/makefile @@ -5,7 +5,9 @@ # # OpenPOWER HostBoot Project # -# COPYRIGHT International Business Machines Corp. 2011,2014 +# Contributors Listed Below - COPYRIGHT 2011,2015 +# [+] International Business Machines Corp. +# # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -54,6 +56,7 @@ SUBDIRS += slave_sbe.d SUBDIRS += pstates.d SUBDIRS += proc_hwreconfig.d SUBDIRS += runtime.d +SUBDIRS += secure_boot.d include ${ROOTPATH}/config.mk diff --git a/src/usr/hwpf/hwp/nest_chiplets/makefile b/src/usr/hwpf/hwp/nest_chiplets/makefile index bda3544d3..18cf3d680 100644 --- a/src/usr/hwpf/hwp/nest_chiplets/makefile +++ b/src/usr/hwpf/hwp/nest_chiplets/makefile @@ -5,7 +5,7 @@ # # OpenPOWER HostBoot Project # -# Contributors Listed Below - COPYRIGHT 2012,2014 +# Contributors Listed Below - COPYRIGHT 2012,2015 # [+] International Business Machines Corp. # # @@ -45,6 +45,7 @@ EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/nest_chiplets/proc_a_x_pci_dmi_pll_s EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/nest_chiplets/proc_pcie_scominit EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/slave_sbe/proc_cen_ref_clk_enable EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/nest_chiplets/proc_pcie_slot_power +EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/secure_boot ## NOTE: add new object files when you add a new HWP OBJS += nest_chiplets.o diff --git a/src/usr/hwpf/hwp/nest_chiplets/proc_a_x_pci_dmi_pll_setup/proc_a_x_pci_dmi_pll_initf.C b/src/usr/hwpf/hwp/nest_chiplets/proc_a_x_pci_dmi_pll_setup/proc_a_x_pci_dmi_pll_initf.C index a9f176c91..b58d55429 100644 --- a/src/usr/hwpf/hwp/nest_chiplets/proc_a_x_pci_dmi_pll_setup/proc_a_x_pci_dmi_pll_initf.C +++ b/src/usr/hwpf/hwp/nest_chiplets/proc_a_x_pci_dmi_pll_setup/proc_a_x_pci_dmi_pll_initf.C @@ -22,7 +22,7 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: proc_a_x_pci_dmi_pll_initf.C,v 1.19 2014/12/02 00:17:23 szhong Exp $ +// $Id: proc_a_x_pci_dmi_pll_initf.C,v 1.20 2015/05/14 21:03:40 jmcgill Exp $ // $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/proc_a_x_pci_dmi_pll_initf.C,v $ //------------------------------------------------------------------------------ // *| @@ -51,7 +51,11 @@ #include <proc_a_x_pci_dmi_pll_initf.H> #include <proc_a_x_pci_dmi_pll_utils.H> -using namespace fapi; + +//------------------------------------------------------------------------------ +// Constant definitons +//------------------------------------------------------------------------------ +const uint32_t DMI_PLL_VCO_WORKAROUND_THRESHOLD_FREQ = 4800; //------------------------------------------------------------------------------ @@ -66,32 +70,27 @@ extern "C" // function: // Scan PLL settings for A/X/PCI/DMI PLLs // -// parameters: i_target => chip target -// i_startX => True to start X BUS PLL, else false -// i_startA => True to start A BUS PLL, else false -// i_startPCIE => True to start PCIE PLL, else false -// i_startDMI => True to start DMI PLL, else false +// parameters: i_target => chip target +// i_startX => True to start X BUS PLL, else false +// i_startA => True to start A BUS PLL, else false +// i_startPCIE => True to start PCIE PLL, else false +// i_startDMI => True to start DMI PLL, else false // returns: FAPI_RC_SUCCESS if operation was successful, else error //------------------------------------------------------------------------------ -fapi::ReturnCode proc_a_x_pci_dmi_pll_initf(const fapi::Target & i_target, - const bool i_startX, - const bool i_startA, - const bool i_startPCIE, - const bool i_startDMI) +fapi::ReturnCode proc_a_x_pci_dmi_pll_initf( + const fapi::Target & i_target, + const bool i_startX, + const bool i_startA, + const bool i_startPCIE, + const bool i_startDMI) { - // data buffer to hold register values - ecmdDataBufferBase scom_data(64); - ecmdDataBufferBase ring_data; + // attribute data uint8_t pcie_enable_attr; uint8_t abus_enable_attr; uint8_t is_simulation; uint8_t lctank_pll_vco_workaround = 0; - uint32_t ring_length = 0; - fapi::ATTR_PROC_AB_BNDY_PLL_DATA_Type attrABRingData={0}; - fapi::ATTR_PROC_PB_BNDY_DMIPLL_DATA_Type attrDMIRingData={0}; - fapi::ATTR_PROC_PCI_BNDY_PLL_DATA_Type attrPCIRingData={0}; + // return codes - uint32_t rc_ecmd = 0; fapi::ReturnCode rc; // mark function entry @@ -169,68 +168,61 @@ fapi::ReturnCode proc_a_x_pci_dmi_pll_initf(const fapi::Target & i_target, } else { - // Read the ring length attribute value. - rc = FAPI_ATTR_GET(ATTR_PROC_AB_BNDY_PLL_LENGTH, &i_target, ring_length); - if (rc) - { - FAPI_ERR("Failed to get attribute: ATTR_PROC_AB_BNDY_PLL_LENGTH."); - break; - } - FAPI_DBG("ATTR_PROC_AB_BNDY_PLL_LENGTH attribute is set to : %d.", ring_length); - - // Read the ring data attribute value. - rc = FAPI_ATTR_GET(ATTR_PROC_AB_BNDY_PLL_DATA, &i_target, attrABRingData); - if (rc) - { - FAPI_ERR("Failed to get attribute: ATTR_PROC_AB_BNDY_PLL_DATA."); - break; - } - - // Set the ring_data buffer to the right length for the ring data - rc_ecmd |= ring_data.setBitLength(ring_length); - if (rc_ecmd) - { - FAPI_ERR("Error 0x%x setting ecmd data buffer length. Buffer must be set to length of scan chain.", rc_ecmd); - rc.setEcmdError(rc_ecmd); - break; - } - - // Put the ring data from the attribute into the buffer - rc_ecmd |= ring_data.insert(attrABRingData, 0, ring_length, 0); - if (rc_ecmd) - { - FAPI_ERR("Error 0x%x loading scan chain attribute data into buffer.", rc_ecmd); - rc.setEcmdError(rc_ecmd); - break; - } - // apply workaround for A PLL for all frequencies bool a_lctank_pll_vco_workaround = (lctank_pll_vco_workaround != 0); FAPI_DBG("A-Bus PLL VCO bug circumvention is %s", (a_lctank_pll_vco_workaround ? "enabled" : "disabled")); - // scan ab_bndy_pll ring with setpulse - FAPI_DBG("Loading the config bits into A BUS PLL"); - rc = proc_a_x_pci_dmi_pll_scan_pll( - i_target, - A_BUS_CHIPLET_0x08000000, - AB_BNDY_PLL_RING_ADDR, - ring_data, - a_lctank_pll_vco_workaround, - AB_BNDY_PLL_RING_CCALLOAD_OFFSET, - AB_BNDY_PLL_RING_CCALFMIN_OFFSET, - false); - if (rc) + // establish base ring state + rc = proc_a_x_pci_dmi_pll_scan_bndy(i_target, + RING_ADDRESS_PROC_AB_BNDY_PLL, + RING_OP_BASE, + RING_BUS_ID_0, + false); + if (!rc.ok()) { - FAPI_ERR("Error from proc_a_x_pci_dmi_pll_scan_pll"); + FAPI_ERR("Error from proc_a_x_pci_dmi_pll_scan_bndy"); break; } + if (a_lctank_pll_vco_workaround) + { + rc = proc_a_x_pci_dmi_pll_scan_bndy(i_target, + RING_ADDRESS_PROC_AB_BNDY_PLL, + RING_OP_MOD_VCO_S1, + RING_BUS_ID_0, + false); + if (!rc.ok()) + { + FAPI_ERR("Error from proc_a_x_pci_dmi_pll_scan_bndy"); + break; + } + + // release PLL (skip lock check) & re-scan + rc = proc_a_x_pci_dmi_pll_release_pll(i_target, + A_BUS_CHIPLET_0x08000000, + false); + if (!rc.ok()) + { + FAPI_ERR("Error from proc_a_x_pci_dmi_pll_release_pll"); + break; + } + + rc = proc_a_x_pci_dmi_pll_scan_bndy(i_target, + RING_ADDRESS_PROC_AB_BNDY_PLL, + RING_OP_MOD_VCO_S2, + RING_BUS_ID_0, + false); + if (!rc.ok()) + { + FAPI_ERR("Error from proc_a_x_pci_dmi_pll_scan_bndy"); + break; + } + } FAPI_INF("Done setting up A-Bus PLL. "); } // end A PLL - //----------// // DMI PLL // //----------// @@ -240,42 +232,6 @@ fapi::ReturnCode proc_a_x_pci_dmi_pll_initf(const fapi::Target & i_target, } else { - // Read the ring length attribute value. - rc = FAPI_ATTR_GET(ATTR_PROC_PB_BNDY_DMIPLL_LENGTH, &i_target, ring_length); - if (rc) - { - FAPI_ERR("Failed to get attribute: ATTR_PROC_PB_BNDY_DMIPLL_LENGTH."); - break; - } - FAPI_DBG("ATTR_PROC_PB_BNDY_DMIPLL_LENGTH attribute is set to : %d.", ring_length); - - - // Read the ring data attribute value. - rc = FAPI_ATTR_GET(ATTR_PROC_PB_BNDY_DMIPLL_DATA, &i_target, attrDMIRingData); - if (rc) - { - FAPI_ERR("Failed to get attribute: ATTR_PROC_PB_BNDY_DMIPLL_DATA."); - break; - } - - // Set the ring_data buffer to the right length for the ring data - rc_ecmd |= ring_data.setBitLength(ring_length); - if (rc_ecmd) - { - FAPI_ERR("Error 0x%x setting ecmd data buffer length. Buffer must be set to length of scan chain.", rc_ecmd); - rc.setEcmdError(rc_ecmd); - break; - } - - // Put the ring data from the attribute into the buffer - rc_ecmd |= ring_data.insert(attrDMIRingData, 0, ring_length, 0); - if (rc_ecmd) - { - FAPI_ERR("Error 0x%x loading scan chain attribute data into buffer.", rc_ecmd); - rc.setEcmdError(rc_ecmd); - break; - } - // only apply DMI workaround if needed when frequency < 4800 MHz, bool dmi_lctank_pll_vco_workaround = (lctank_pll_vco_workaround != 0); uint32_t dmi_freq; @@ -299,28 +255,57 @@ fapi::ReturnCode proc_a_x_pci_dmi_pll_initf(const fapi::Target & i_target, FAPI_DBG("DMI PLL VCO bug circumvention is %s", (dmi_lctank_pll_vco_workaround ? "enabled" : "disabled")); - // scan pb_bndy_dmipll ring with setpulse - FAPI_DBG("Loading the config bits into DMI PLL"); - rc = proc_a_x_pci_dmi_pll_scan_pll( - i_target, - NEST_CHIPLET_0x02000000, - PB_BNDY_DMIPLL_RING_ADDR, - ring_data, - dmi_lctank_pll_vco_workaround, - PB_BNDY_DMIPLL_RING_CCALLOAD_OFFSET, - PB_BNDY_DMIPLL_RING_CCALFMIN_OFFSET, - true); - if (rc) + // establish base ring state + rc = proc_a_x_pci_dmi_pll_scan_bndy(i_target, + RING_ADDRESS_PROC_PB_BNDY_DMIPLL, + RING_OP_BASE, + RING_BUS_ID_0, + true); + if (!rc.ok()) { - FAPI_ERR("Error from proc_a_x_pci_dmi_pll_scan_pll"); + FAPI_ERR("Error from proc_a_x_pci_dmi_pll_scan_bndy"); break; } + if (dmi_lctank_pll_vco_workaround) + { + rc = proc_a_x_pci_dmi_pll_scan_bndy(i_target, + RING_ADDRESS_PROC_PB_BNDY_DMIPLL, + RING_OP_MOD_VCO_S1, + RING_BUS_ID_0, + true); + if (!rc.ok()) + { + FAPI_ERR("Error from proc_a_x_pci_dmi_pll_scan_bndy"); + break; + } + + // release PLL (skip lock check) & re-scan + rc = proc_a_x_pci_dmi_pll_release_pll(i_target, + NEST_CHIPLET_0x02000000, + false); + if (!rc.ok()) + { + FAPI_ERR("Error from proc_a_x_pci_dmi_pll_release_pll"); + break; + } + + rc = proc_a_x_pci_dmi_pll_scan_bndy(i_target, + RING_ADDRESS_PROC_PB_BNDY_DMIPLL, + RING_OP_MOD_VCO_S2, + RING_BUS_ID_0, + true); + if (!rc.ok()) + { + FAPI_ERR("Error from proc_a_x_pci_dmi_pll_scan_bndy"); + break; + } + } + FAPI_INF("Done setting up DMI PLL. "); } // end DMI PLL - //-----------// // PCIE PLL // //-----------// @@ -345,64 +330,21 @@ fapi::ReturnCode proc_a_x_pci_dmi_pll_initf(const fapi::Target & i_target, } else { - FAPI_DBG("Loading the config bits into PCIE BUS PLL"); - - // Read the ring length attribute value. - rc = FAPI_ATTR_GET(ATTR_PROC_PCI_BNDY_PLL_LENGTH, &i_target, ring_length); - if (rc) - { - FAPI_ERR("Failed to get attribute: ATTR_PROC_PCI_BNDY_PLL_LENGTH."); - break; - } - FAPI_DBG("ATTR_PROC_PCI_BNDY_PLL_LENGTH attribute is set to : %d.", ring_length); - - // Read the ring data attribute value. - rc = FAPI_ATTR_GET(ATTR_PROC_PCI_BNDY_PLL_DATA, &i_target, attrPCIRingData); - if (rc) - { - FAPI_ERR("Failed to get attribute: ATTR_PROC_PCI_BNDY_PLL_DATA."); - break; - } - - // Set the ring_data buffer to the right length for the ring data - rc_ecmd |= ring_data.setBitLength(ring_length); - if (rc_ecmd) - { - FAPI_ERR("Error 0x%x setting ecmd data buffer length. Buffer must be set to length of scan chain.", rc_ecmd); - rc.setEcmdError(rc_ecmd); - break; - } - - // Put the ring data from the attribute into the buffer - rc_ecmd |= ring_data.insert(attrPCIRingData, 0, ring_length, 0); - if (rc_ecmd) - { - FAPI_ERR("Error 0x%x loading scan chain attribute data into buffer.", rc_ecmd); - rc.setEcmdError(rc_ecmd); - break; - } - - // scan pci_bndy_pll ring with setpulse - rc = proc_a_x_pci_dmi_pll_scan_pll( - i_target, - PCIE_CHIPLET_0x09000000, - PCI_BNDY_PLL_RING_ADDR, - ring_data, - false, - PCI_BNDY_PLL_RING_CCALLOAD_OFFSET, - PCI_BNDY_PLL_RING_CCALFMIN_OFFSET, - false); - if (rc) + // establish base ring state + rc = proc_a_x_pci_dmi_pll_scan_bndy(i_target, + RING_ADDRESS_PROC_PCI_BNDY_PLL, + RING_OP_BASE, + RING_BUS_ID_0, + false); + if (!rc.ok()) { - FAPI_ERR("Error from proc_a_x_pci_dmi_pll_scan_pll"); + FAPI_ERR("Error from proc_a_x_pci_dmi_pll_scan_bndy"); break; } FAPI_INF("Done setting up PCIE PLL."); } // end PCIE PLL - - } while (0); // end do // mark function exit @@ -418,6 +360,9 @@ fapi::ReturnCode proc_a_x_pci_dmi_pll_initf(const fapi::Target & i_target, This section is automatically updated by CVS when you check in this file. Be sure to create CVS comments when you commit so that they can be included here. $Log: proc_a_x_pci_dmi_pll_initf.C,v $ +Revision 1.20 2015/05/14 21:03:40 jmcgill +Update to use modified proc_a_x_pci_dmi_pll_utils API + Revision 1.19 2014/12/02 00:17:23 szhong remove hardcoded bndy pll length in code diff --git a/src/usr/hwpf/hwp/nest_chiplets/proc_a_x_pci_dmi_pll_setup/proc_a_x_pci_dmi_pll_initf.H b/src/usr/hwpf/hwp/nest_chiplets/proc_a_x_pci_dmi_pll_setup/proc_a_x_pci_dmi_pll_initf.H index f70900b60..c7f14c671 100644 --- a/src/usr/hwpf/hwp/nest_chiplets/proc_a_x_pci_dmi_pll_setup/proc_a_x_pci_dmi_pll_initf.H +++ b/src/usr/hwpf/hwp/nest_chiplets/proc_a_x_pci_dmi_pll_setup/proc_a_x_pci_dmi_pll_initf.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2012,2014 */ +/* Contributors Listed Below - COPYRIGHT 2012,2015 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -22,7 +22,7 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: proc_a_x_pci_dmi_pll_initf.H,v 1.4 2013/09/30 16:09:57 jmcgill Exp $ +// $Id: proc_a_x_pci_dmi_pll_initf.H,v 1.5 2015/05/14 21:03:42 jmcgill Exp $ // $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/proc_a_x_pci_dmi_pll_initf.H,v $ //------------------------------------------------------------------------------ // *| @@ -40,10 +40,10 @@ #ifndef _PROC_A_X_PCI_DMI_PLL_INITF_H_ #define _PROC_A_X_PCI_DMI_PLL_INITF_H_ + //------------------------------------------------------------------------------ // Includes //------------------------------------------------------------------------------ - #include <fapi.H> @@ -53,7 +53,10 @@ // function pointer typedef definition for HWP call support typedef fapi::ReturnCode (*proc_a_x_pci_dmi_pll_initf_FP_t)(const fapi::Target &, - const bool, const bool, const bool, const bool); + const bool, + const bool, + const bool, + const bool); //------------------------------------------------------------------------------ // Function prototypes @@ -66,18 +69,18 @@ extern "C" * @brief Scan PLL settings for A/X/PCI/DMI PLLs * * @param[in] i_target Reference to target - * @param[in] i_startX True if x_bus PLL should be initalized, else false + * @param[in] i_startX True if X PLL should be initalized, else false * @param[in] i_startA True if A PLL should be initalized, else false * @param[in] i_startPCIE True if PCIE PLL should be initalized, else false * @param[in] i_startDMI True if DMI PLL should be initalized, else false * * @return ReturnCode */ - fapi::ReturnCode proc_a_x_pci_dmi_pll_initf(const fapi::Target & i_target, - const bool i_startX, - const bool i_startA, - const bool i_startPCIE, - const bool i_startDMI); +fapi::ReturnCode proc_a_x_pci_dmi_pll_initf(const fapi::Target & i_target, + const bool i_startX, + const bool i_startA, + const bool i_startPCIE, + const bool i_startDMI); } // extern "C" diff --git a/src/usr/hwpf/hwp/nest_chiplets/proc_a_x_pci_dmi_pll_setup/proc_a_x_pci_dmi_pll_utils.C b/src/usr/hwpf/hwp/nest_chiplets/proc_a_x_pci_dmi_pll_setup/proc_a_x_pci_dmi_pll_utils.C index 9ce62f753..de733a395 100644 --- a/src/usr/hwpf/hwp/nest_chiplets/proc_a_x_pci_dmi_pll_setup/proc_a_x_pci_dmi_pll_utils.C +++ b/src/usr/hwpf/hwp/nest_chiplets/proc_a_x_pci_dmi_pll_setup/proc_a_x_pci_dmi_pll_utils.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2013,2014 */ +/* Contributors Listed Below - COPYRIGHT 2013,2015 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -22,18 +22,18 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: proc_a_x_pci_dmi_pll_utils.C,v 1.7 2014/02/03 16:29:10 mfred Exp $ +// $Id: proc_a_x_pci_dmi_pll_utils.C,v 1.9 2015/08/14 16:31:17 thi Exp $ // $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/proc_a_x_pci_dmi_pll_utils.C,v $ //------------------------------------------------------------------------------ // *| -// *! (C) Copyright International Business Machines Corp. 2012 +// *! (C) Copyright International Business Machines Corp. 2015 // *! All Rights Reserved -- Property of IBM // *! *** *** // *| // *! TITLE : proc_a_x_pci_dmi_pll_utils.C -// *! DESCRIPTION : Configure the PLLs +// *! DESCRIPTION : PLL configuration utility functions // *! -// *! OWNER NAME : Ralph Koester Email: rkoester@de.ibm.com +// *! OWNER NAME : Joe McGill Email: jmcgill@us.ibm.com // *! //------------------------------------------------------------------------------ @@ -43,16 +43,43 @@ //------------------------------------------------------------------------------ #include <p8_scom_addresses.H> #include <proc_a_x_pci_dmi_pll_utils.H> -#include <fapi.H> - -using namespace fapi; +#include <p8_istep_num.H> +#include <proc_sbe_scan_service.H> +#include <proc_use_sbe_scan_service.H> //------------------------------------------------------------------------------ // Constant definitions //------------------------------------------------------------------------------ -// lock polling constants +// SBE polling constants +const uint32_t PROC_A_X_PCI_DMI_PLL_UTILS_SBE_MAX_POLLS = 100; +const uint32_t PROC_A_X_PCI_DMI_PLL_UTILS_SBE_POLL_DELAY_HW = 2000000; +const uint32_t PROC_A_X_PCI_DMI_PLL_UTILS_SBE_POLL_DELAY_SIM = 0; + +// SBE Control Register field/bit definitions +const uint32_t SBE_CONTROL_REG_CTL_NO_LB_BIT = 0; + +// SBE Mailbox0 Register scan request format constants +const uint32_t MBOX0_REQUEST_VALID_BIT = 0; +const uint32_t MBOX0_RING_SELECT_START_BIT = 6; +const uint32_t MBOX0_RING_SELECT_END_BIT = 7; +const uint32_t MBOX0_RING_OP_START_BIT = 9; +const uint32_t MBOX0_RING_OP_END_BIT = 11; +const uint32_t MBOX0_RING_BUS_ID_START_BIT = 13; +const uint32_t MBOX0_RING_BUS_ID_END_BIT = 15; + +// SBE MBOX1 Scratch Register scan reply format constants +const uint32_t MBOX1_SCAN_REPLY_SUCCESS_BIT = 0; + +// VCO PLL workaround ring offsets +const uint32_t PB_BNDY_DMIPLL_RING_CCALLOAD_OFFSET = 580; +const uint32_t PB_BNDY_DMIPLL_RING_CCALFMIN_OFFSET = 581; + +const uint32_t AB_BNDY_PLL_RING_CCALLOAD_OFFSET = 278; +const uint32_t AB_BNDY_PLL_RING_CCALFMIN_OFFSET = 279; + +// PLL lock polling constants const uint32_t PROC_A_X_PCI_DMI_PLL_UTILS_MAX_LOCK_POLLS = 50; const uint32_t PROC_A_X_PCI_DMI_PLL_UTILS_POLL_DELAY_HW = 2000000; const uint32_t PROC_A_X_PCI_DMI_PLL_UTILS_POLL_DELAY_SIM = 1; @@ -77,93 +104,875 @@ const uint8_t PLL_LOCK_REG_LOCK_END_BIT = 3; //------------------------------------------------------------------------------ -// Function definition +// Function definitions //------------------------------------------------------------------------------ extern "C" { +using namespace fapi; //------------------------------------------------------------------------------ // function: -// Scan PLL boundary ring with setpulse +// Calculate state to apply to Centaur tp_bndy_pll ring // -// parameters: i_target => chip target -// i_chiplet_base_scom_addr => aligned base address of chiplet SCOM -// address space -// i_pll_ring_addr => PLL ring address -// i_pll_ring_data => data buffer containing full PLL ring -// content -// i_mask_scan_collision => mask scan collision bit in chiplet -// pervasive LFIR +// parameters: i_target => chip target +// i_pll_ring_op => modification to be made to PLL content +// o_ring_data => data buffer containing ring state to apply // returns: FAPI_RC_SUCCESS if operation was successful, else error //------------------------------------------------------------------------------ +fapi::ReturnCode p8_pll_utils_calc_memb_tp_bndy_pll( + const fapi::Target & i_target, + const p8_pll_utils_ring_op i_pll_ring_op, + ecmdDataBufferBase & o_ring_data) +{ + // return codes + uint32_t rc_ecmd = 0; + fapi::ReturnCode rc; -fapi::ReturnCode proc_a_x_pci_dmi_pll_scan_bndy( - const fapi::Target& i_target, - const uint32_t i_chiplet_base_scom_addr, - const uint32_t i_pll_ring_addr, - ecmdDataBufferBase& i_pll_ring_data, - const bool i_mask_scan_collision) + // mark function entry + FAPI_DBG("Start"); + + do + { + // determine ring length + fapi::ATTR_MEMB_TP_BNDY_PLL_LENGTH_Type ring_length; + rc = FAPI_ATTR_GET(ATTR_MEMB_TP_BNDY_PLL_LENGTH, &i_target, ring_length); + if (!rc.ok()) + { + FAPI_ERR("Failed to get attribute: ATTR_MEMB_TP_BNDY_PLL_LENGTH."); + break; + } + rc_ecmd |= o_ring_data.setBitLength(ring_length); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting ecmd data buffer length. Buffer must be set to length of scan chain.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + + // determine starting ring state + if (i_pll_ring_op == RING_OP_BASE) + { + // start from attribute data + fapi::ATTR_MEMB_TP_BNDY_PLL_DATA_Type ring_data_attr = {0}; + rc = FAPI_ATTR_GET(ATTR_MEMB_TP_BNDY_PLL_DATA, &i_target, ring_data_attr); + if (rc) + { + FAPI_ERR("Failed to get attribute: ATTR_MEMB_TP_BNDY_PLL_DATA."); + break; + } + rc_ecmd |= o_ring_data.insert(ring_data_attr, 0, ring_length, 0); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x loading scan chain attribute data into buffer.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + } + else + { + // start from data currently in ring + rc = fapiGetRing(i_target, RING_ADDRESS_MEMB_TP_BNDY_PLL, o_ring_data, fapi::RING_MODE_SET_PULSE); + if (!rc.ok()) + { + FAPI_ERR("Error from fapiGetRing (ring ID: 0x08%x)", RING_ADDRESS_MEMB_TP_BNDY_PLL); + break; + } + } + + // modify ring data + if (i_pll_ring_op == RING_OP_MOD_REFCLK_SEL) + { + fapi::ATTR_MEMB_DMI_CUPLL_REFCLKSEL_OFFSET_Type refclksel_offset; + rc = FAPI_ATTR_GET(ATTR_MEMB_DMI_CUPLL_REFCLKSEL_OFFSET, &i_target, refclksel_offset); + if (!rc.ok()) + { + FAPI_ERR("Failed to get attribute: ATTR_MEMB_DMI_CUPLL_REFCLKSEL_OFFSET"); + break; + } + + if (o_ring_data.isBitClear(refclksel_offset)) + { + rc_ecmd |= o_ring_data.setBit(refclksel_offset); + } + else + { + rc_ecmd |= o_ring_data.clearBit(refclksel_offset); + } + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x loading refclock select attribute data into buffer.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + } + else if (i_pll_ring_op == RING_OP_MOD_PFD360) + { + fapi::ATTR_MEMB_DMI_CUPLL_PFD360_OFFSET_Type pfd360_offset; + rc = FAPI_ATTR_GET(ATTR_MEMB_DMI_CUPLL_PFD360_OFFSET, &i_target, pfd360_offset); + if (!rc.ok()) + { + FAPI_ERR("Failed to get attribute: ATTR_MEMB_DMI_CUPLL_PFD360_OFFSET"); + break; + } + + if (o_ring_data.isBitClear(pfd360_offset)) + { + rc_ecmd |= o_ring_data.setBit(pfd360_offset); + } + else + { + rc_ecmd |= o_ring_data.clearBit(pfd360_offset); + } + + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x loading pfd360 attribute data into buffer.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + } + } while(0); + + // mark function exit + FAPI_DBG("End"); + + return rc; +} + + +//------------------------------------------------------------------------------ +// function: +// Calculate state to apply to processor pci_bndy_pll ring +// +// parameters: i_target => chip target +// o_ring_data => data buffer containing ring state to apply +// returns: FAPI_RC_SUCCESS if operation was successful, else error +//------------------------------------------------------------------------------ +fapi::ReturnCode p8_pll_utils_calc_proc_pci_bndy_pll( + const fapi::Target & i_target, + ecmdDataBufferBase & o_ring_data) { - // data buffer to hold SCOM data - ecmdDataBufferBase data(64); + // return codes + uint32_t rc_ecmd = 0; + fapi::ReturnCode rc; + + // mark function entry + FAPI_DBG("Start"); + do + { + // determine ring length + fapi::ATTR_PROC_PCI_BNDY_PLL_LENGTH_Type ring_length; + rc = FAPI_ATTR_GET(ATTR_PROC_PCI_BNDY_PLL_LENGTH, &i_target, ring_length); + if (!rc.ok()) + { + FAPI_ERR("Failed to get attribute: ATTR_PROC_PCI_BNDY_PLL_LENGTH."); + break; + } + rc_ecmd |= o_ring_data.setBitLength(ring_length); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting ecmd data buffer length. Buffer must be set to length of scan chain.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + + // determine starting ring state + fapi::ATTR_PROC_PCI_BNDY_PLL_DATA_Type ring_data_attr = {0}; + rc = FAPI_ATTR_GET(ATTR_PROC_PCI_BNDY_PLL_DATA, &i_target, ring_data_attr); + if (rc) + { + FAPI_ERR("Failed to get attribute: ATTR_PROC_PCI_BNDY_PLL_DATA."); + break; + } + rc_ecmd |= o_ring_data.insert(ring_data_attr, 0, ring_length, 0); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x loading scan chain attribute data into buffer.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + } while(0); + + // mark function exit + FAPI_DBG("End"); + + return rc; +} + + +//------------------------------------------------------------------------------ +// function: +// Calculate state to apply to processor pb_bndy_dmipll ring +// +// parameters: i_target => chip target +// i_pll_ring_op => modification to be made to base PLL content +// i_pll_bus_id => bus instance to target for modification +// o_ring_data => data buffer containing ring state to apply +// returns: FAPI_RC_SUCCESS if operation was successful, else error +//------------------------------------------------------------------------------ +fapi::ReturnCode p8_pll_utils_calc_proc_pb_bndy_dmipll( + const fapi::Target & i_target, + const p8_pll_utils_ring_op i_pll_ring_op, + const p8_pll_utils_bus_id i_pll_bus_id, + ecmdDataBufferBase & o_ring_data) +{ // return codes uint32_t rc_ecmd = 0; fapi::ReturnCode rc; - bool unmask_scan_collision = false; // mark function entry FAPI_DBG("Start"); do { - //------------------------------------------- - // Mask Pervasive LFIR - //------------------------------------------ + // determine ring length + fapi::ATTR_PROC_PB_BNDY_DMIPLL_LENGTH_Type ring_length; + rc = FAPI_ATTR_GET(ATTR_PROC_PB_BNDY_DMIPLL_LENGTH, &i_target, ring_length); + if (!rc.ok()) + { + FAPI_ERR("Failed to get attribute: ATTR_PROC_PB_BNDY_DMIPLL_LENGTH."); + break; + } + rc_ecmd |= o_ring_data.setBitLength(ring_length); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting ecmd data buffer length. Buffer must be set to length of scan chain.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } - if (i_mask_scan_collision) + // determine starting ring state + if (i_pll_ring_op == RING_OP_BASE) { - FAPI_DBG("Reading value of Pervasive LFIR scan collision mask bit ..."); - rc = fapiGetScom(i_target, i_chiplet_base_scom_addr | GENERIC_PERV_LFIR_MASK_0x0004000D, data); + // start from attribute data + fapi::ATTR_PROC_PB_BNDY_DMIPLL_DATA_Type ring_data_attr = {0}; + rc = FAPI_ATTR_GET(ATTR_PROC_PB_BNDY_DMIPLL_DATA, &i_target, ring_data_attr); + if (rc) + { + FAPI_ERR("Failed to get attribute: ATTR_PROC_PB_BNDY_DMIPLL_DATA."); + break; + } + rc_ecmd |= o_ring_data.insert(ring_data_attr, 0, ring_length, 0); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x loading scan chain attribute data into buffer.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + } + else + { + // start from data currently in ring + rc = fapiGetRing(i_target, RING_ADDRESS_PROC_PB_BNDY_DMIPLL, o_ring_data, fapi::RING_MODE_SET_PULSE); if (!rc.ok()) { - FAPI_ERR("Error reading Pervasive LFIR Mask OR Register."); + FAPI_ERR("Error from fapiGetRing (ring ID: 0x08%x)", RING_ADDRESS_PROC_PB_BNDY_DMIPLL); break; } - unmask_scan_collision = data.isBitClear(PERV_LFIR_SCAN_COLLISION_BIT); + } - FAPI_DBG("Masking Pervasive LFIR scan collision bit ..."); - rc_ecmd |= data.flushTo0(); - rc_ecmd |= data.setBit(PERV_LFIR_SCAN_COLLISION_BIT); + // modify ring data + if (i_pll_ring_op == RING_OP_MOD_VCO_S1) + { + rc_ecmd |= o_ring_data.setBit(PB_BNDY_DMIPLL_RING_CCALLOAD_OFFSET); + rc_ecmd |= o_ring_data.setBit(PB_BNDY_DMIPLL_RING_CCALFMIN_OFFSET); if (rc_ecmd) { - FAPI_ERR("Error 0x%x setting up ecmd data buffer to set Pervasive LFIR Mask Register.", rc_ecmd); + FAPI_ERR("Error 0x%x setting up data buffer to enable lctank PLL vco workaround (scan1)", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + } + else if (i_pll_ring_op == RING_OP_MOD_VCO_S2) + { + rc_ecmd |= o_ring_data.setBit(PB_BNDY_DMIPLL_RING_CCALLOAD_OFFSET); + rc_ecmd |= o_ring_data.clearBit(PB_BNDY_DMIPLL_RING_CCALFMIN_OFFSET); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting up data buffer to enable lctank PLL vco workaround (scan2)", rc_ecmd); rc.setEcmdError(rc_ecmd); break; } - rc = fapiPutScom(i_target, i_chiplet_base_scom_addr | GENERIC_PERV_LFIR_MASK_OR_0x0004000F, data); + } + else if (i_pll_ring_op == RING_OP_MOD_REFCLK_SEL) + { + fapi::ATTR_PROC_DMI_CUPLL_REFCLKSEL_OFFSET_Type refclksel_offset = {0}; + rc = FAPI_ATTR_GET(ATTR_PROC_DMI_CUPLL_REFCLKSEL_OFFSET, &i_target, refclksel_offset); if (!rc.ok()) { - FAPI_ERR("Error writing Pervasive LFIR Mask OR Register."); + FAPI_ERR("Failed to get attribute: ATTR_PROC_DMI_CUPLL_REFCLKSEL_OFFSET"); + break; + } + + if (o_ring_data.isBitSet(refclksel_offset[i_pll_bus_id])) + { + rc_ecmd |= o_ring_data.clearBit(refclksel_offset[i_pll_bus_id]); + } + else + { + rc_ecmd |= o_ring_data.setBit(refclksel_offset[i_pll_bus_id]); + } + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x loading refclock select attribute data into buffer.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + } + else if (i_pll_ring_op == RING_OP_MOD_PFD360) + { + fapi::ATTR_PROC_DMI_CUPLL_PFD360_OFFSET_Type pfd360_offset; + rc = FAPI_ATTR_GET(ATTR_PROC_DMI_CUPLL_PFD360_OFFSET, &i_target, pfd360_offset); + if (!rc.ok()) + { + FAPI_ERR("Failed to get attribute: ATTR_PROC_DMI_CUPLL_PFD360_OFFSET"); + break; + } + + if (o_ring_data.isBitSet(pfd360_offset[i_pll_bus_id])) + { + rc_ecmd |= o_ring_data.clearBit(pfd360_offset[i_pll_bus_id]); + } + else + { + rc_ecmd |= o_ring_data.setBit(pfd360_offset[i_pll_bus_id]); + } + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x loading pfd360 attribute data into buffer.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + } + } while(0); + + // mark function exit + FAPI_DBG("End"); + + return rc; +} + + +//------------------------------------------------------------------------------ +// function: +// Calculate state to apply to processor ab_bndy_pll ring +// +// parameters: i_target => chip target +// i_pll_ring_op => modification to be made to base PLL content +// i_pll_bus_id => bus instance to target for modification +// o_ring_data => data buffer containing ring state to apply +// returns: FAPI_RC_SUCCESS if operation was successful, else error +//------------------------------------------------------------------------------ +fapi::ReturnCode p8_pll_utils_calc_proc_ab_bndy_pll( + const fapi::Target & i_target, + const p8_pll_utils_ring_op i_pll_ring_op, + const p8_pll_utils_bus_id i_pll_bus_id, + ecmdDataBufferBase & o_ring_data) +{ + // return codes + uint32_t rc_ecmd = 0; + fapi::ReturnCode rc; + + // mark function entry + FAPI_DBG("Start"); + + do + { + // determine ring length + fapi::ATTR_PROC_AB_BNDY_PLL_LENGTH_Type ring_length; + rc = FAPI_ATTR_GET(ATTR_PROC_AB_BNDY_PLL_LENGTH, &i_target, ring_length); + if (!rc.ok()) + { + FAPI_ERR("Failed to get attribute: ATTR_PROC_AB_BNDY_PLL_LENGTH."); + break; + } + rc_ecmd |= o_ring_data.setBitLength(ring_length); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting ecmd data buffer length. Buffer must be set to length of scan chain.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + + // determine starting ring state + if (i_pll_ring_op == RING_OP_BASE) + { + // start from attribute data + fapi::ATTR_PROC_AB_BNDY_PLL_DATA_Type ring_data_attr = {0}; + rc = FAPI_ATTR_GET(ATTR_PROC_AB_BNDY_PLL_DATA, &i_target, ring_data_attr); + if (rc) + { + FAPI_ERR("Failed to get attribute: ATTR_PROC_AB_BNDY_PLL_DATA."); + break; + } + rc_ecmd |= o_ring_data.insert(ring_data_attr, 0, ring_length, 0); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x loading scan chain attribute data into buffer.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + } + else + { + // start from data currently in ring + rc = fapiGetRing(i_target, RING_ADDRESS_PROC_AB_BNDY_PLL, o_ring_data, fapi::RING_MODE_SET_PULSE); + if (!rc.ok()) + { + FAPI_ERR("Error from fapiGetRing (ring ID: 0x08%x)", RING_ADDRESS_PROC_AB_BNDY_PLL); break; } } - //------------------------------------------- - // Set the OPCG to generate the setpulse - //------------------------------------------ + // modify ring data + if (i_pll_ring_op == RING_OP_MOD_VCO_S1) + { + rc_ecmd |= o_ring_data.setBit(AB_BNDY_PLL_RING_CCALLOAD_OFFSET); + rc_ecmd |= o_ring_data.setBit(AB_BNDY_PLL_RING_CCALFMIN_OFFSET); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting up data buffer to enable lctank PLL vco workaround (scan1)", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + } + else if (i_pll_ring_op == RING_OP_MOD_VCO_S2) + { + rc_ecmd |= o_ring_data.setBit(AB_BNDY_PLL_RING_CCALLOAD_OFFSET); + rc_ecmd |= o_ring_data.clearBit(AB_BNDY_PLL_RING_CCALFMIN_OFFSET); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting up data buffer to enable lctank PLL vco workaround (scan2)", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + } + else if (i_pll_ring_op == RING_OP_MOD_REFCLK_SEL) + { + fapi::ATTR_PROC_ABUS_CUPLL_REFCLKSEL_OFFSET_Type refclksel_offset = {0}; + rc = FAPI_ATTR_GET(ATTR_PROC_ABUS_CUPLL_REFCLKSEL_OFFSET, &i_target, refclksel_offset); + if (!rc.ok()) + { + FAPI_ERR("Failed to get attribute: ATTR_PROC_ABUS_CUPLL_REFCLKSEL_OFFSET"); + break; + } + if (o_ring_data.isBitSet(refclksel_offset[i_pll_bus_id])) + { + rc_ecmd |= o_ring_data.clearBit(refclksel_offset[i_pll_bus_id]); + } + else + { + rc_ecmd |= o_ring_data.setBit(refclksel_offset[i_pll_bus_id]); + } + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x loading refclock select attribute data into buffer.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + } + else if (i_pll_ring_op == RING_OP_MOD_PFD360) + { + fapi::ATTR_PROC_ABUS_CUPLL_PFD360_OFFSET_Type pfd360_offset; + rc = FAPI_ATTR_GET(ATTR_PROC_ABUS_CUPLL_PFD360_OFFSET, &i_target, pfd360_offset); + if (!rc.ok()) + { + FAPI_ERR("Failed to get attribute: ATTR_PROC_ABUS_CUPLL_PFD360_OFFSET"); + break; + } + + if (o_ring_data.isBitSet(pfd360_offset[i_pll_bus_id])) + { + rc_ecmd |= o_ring_data.clearBit(pfd360_offset[i_pll_bus_id]); + } + else + { + rc_ecmd |= o_ring_data.setBit(pfd360_offset[i_pll_bus_id]); + } + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x loading pfd360 attribute data into buffer.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + } + } while(0); + + // mark function exit + FAPI_DBG("End"); + return rc; +} + + +//------------------------------------------------------------------------------ +// function: +// Poll for SBE to reach designated state (interlocked with scan requests) +// +// parameters: i_target => chip target +// i_poll_limit => number of polls permitted before timeout +// +// returns: FAPI_RC_SUCCESS if desired state was reached, else error +//------------------------------------------------------------------------------ +fapi::ReturnCode p8_pll_utils_poll_sbe( + const fapi::Target & i_target, + const uint32_t i_num_polls) +{ + fapi::ReturnCode rc; + uint32_t rc_ecmd = 0; + + uint32_t poll_num = 0; + bool poll_timeout = false; + bool sbe_running = true; + bool sbe_ready = false; + + ecmdDataBufferBase sbe_control_data(64); + ecmdDataBufferBase sbe_vital_data(64); + uint32_t istep_num; + uint8_t substep_num; + ecmdDataBufferBase mbox_data(64); + + // mark function entry + FAPI_DBG("Start"); + + do + { + do + { + // delay between poll attempts + if (poll_num) + { + FAPI_DBG("Pausing prior to next poll..."); + rc = fapiDelay(PROC_A_X_PCI_DMI_PLL_UTILS_SBE_POLL_DELAY_HW, + PROC_A_X_PCI_DMI_PLL_UTILS_SBE_POLL_DELAY_SIM); + if (!rc.ok()) + { + FAPI_ERR("Error from fapiDelay"); + break; + } + } + + // increment poll count, timeout if threshold exceeded + poll_num++; + if (poll_num > i_num_polls) + { + poll_timeout = true; + break; + } + + // determine SBE run state + FAPI_DBG("Reading SBE state (poll %d / %d)", poll_num, i_num_polls); + rc = fapiGetScom(i_target, PORE_SBE_CONTROL_0x000E0001, sbe_control_data); + if (!rc.ok()) + { + FAPI_ERR("Error reading SBE Control Register"); + break; + } + sbe_running = sbe_control_data.isBitClear(SBE_CONTROL_REG_CTL_NO_LB_BIT); + FAPI_DBG("Run state: %s", ((sbe_running)?("run"):("halted"))); + + // get SBE istep/substep information + rc = fapiGetScom(i_target, MBOX_SBEVITAL_0x0005001C, sbe_vital_data); + if (!rc.ok()) + { + FAPI_ERR("Error reading SBE Vital Register"); + break; + } + + rc_ecmd |= sbe_vital_data.extractToRight(&istep_num, + ISTEP_NUM_BIT_POSITION, + ISTEP_NUM_BIT_LENGTH); + rc_ecmd |= sbe_vital_data.extractToRight(&substep_num, + SUBSTEP_NUM_BIT_POSITION, + SUBSTEP_NUM_BIT_LENGTH); + if (rc_ecmd) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + + // get HB->SBE request mailbox, check that it is clear + rc = fapiGetScom(i_target, MBOX_SCRATCH_REG0_0x00050038, mbox_data); + if (!rc.ok()) + { + FAPI_ERR("Scom error reading SBE MBOX0 Register"); + break; + } + + sbe_ready = (istep_num == PROC_SBE_SCAN_SERVICE_ISTEP_NUM) && + (substep_num == SUBSTEP_SBE_READY) && + (mbox_data.getDoubleWord(0) == 0); + + FAPI_DBG("Istep: 0x%03X, Substep: %X, MBOX: %016llX", istep_num, substep_num, mbox_data.getDoubleWord(0)); + + } while (!poll_timeout && + sbe_running && + !sbe_ready); + + if (!rc.ok()) + { + break; + } + if (!sbe_running) + { + FAPI_ERR("SBE is NOT running!"); + const fapi::Target & TARGET = i_target; + ecmdDataBufferBase & SBE_CONTROL = sbe_control_data; + FAPI_SET_HWP_ERROR(rc, RC_P8_PLL_UTILS_SBE_STOPPED); + break; + } + if (poll_timeout || !sbe_ready) + { + FAPI_ERR("Poll limit reached waiting for SBE to attain expected state"); + FAPI_ERR("Expected istep 0x%03llX, substep 0x%X but found istep 0x%03X, substep 0x%X", + PROC_SBE_SCAN_SERVICE_ISTEP_NUM, SUBSTEP_SBE_READY, + istep_num, substep_num); + const fapi::Target & TARGET = i_target; + const uint32_t & POLL_COUNT = i_num_polls; + const ecmdDataBufferBase & SBE_VITAL = sbe_vital_data; + FAPI_SET_HWP_ERROR(rc, RC_P8_PLL_UTILS_SBE_TIMEOUT_ERROR); + break; + } + + FAPI_DBG("SBE reached expected state"); + + } while(0); + + // mark function entry + FAPI_DBG("End"); + return rc; +} + + +//------------------------------------------------------------------------------ +// function: +// Scan PLL boundary ring with setpulse (scan executed by SBE) +// +// parameters: i_target => chip target +// i_pll_ring_addr => PLL ring address +// i_pll_ring_op => modification to be made to base PLL content +// i_pll_bus_id => bus instance to target for modification +// returns: FAPI_RC_SUCCESS if operation was successful, else error +//------------------------------------------------------------------------------ +fapi::ReturnCode p8_pll_utils_scan_bndy_sbe( + const fapi::Target & i_target, + const p8_pll_utils_ring_address i_pll_ring_addr, + const p8_pll_utils_ring_op i_pll_ring_op, + const p8_pll_utils_bus_id i_pll_bus_id) +{ + // return codes + fapi::ReturnCode rc; + uint32_t rc_ecmd = 0; + + // mark function entry + FAPI_DBG("Start"); + + do + { + // check request content + p8_pll_utils_ring_id pll_ring_id; + if (i_pll_ring_addr == RING_ADDRESS_PROC_AB_BNDY_PLL) + { + pll_ring_id = RING_ID_ABUS; + } + else if (i_pll_ring_addr == RING_ADDRESS_PROC_PCI_BNDY_PLL) + { + pll_ring_id = RING_ID_PCI; + } + else if (i_pll_ring_addr == RING_ADDRESS_PROC_PB_BNDY_DMIPLL) + { + pll_ring_id = RING_ID_DMI; + } + else + { + FAPI_ERR("Invalid/unsupported SBE ring operation requested"); + const fapi::Target & TARGET = i_target; + const p8_pll_utils_ring_address & PLL_RING_ADDR = i_pll_ring_addr; + const p8_pll_utils_ring_op & PLL_RING_OP = i_pll_ring_op; + const p8_pll_utils_bus_id & PLL_BUS_ID = i_pll_bus_id; + const bool & INVALID_RING_ADDRESS = true; + const bool & INVALID_RING_OP = false; + const bool & INVALID_BUS_ID = false; + FAPI_SET_HWP_ERROR(rc, RC_P8_PLL_UTILS_INVALID_OPERATION); + break; + } + + // verify that SBE is ready to service scan operation + // (it should be waiting for our request) + FAPI_DBG("Checking SBE is ready to receive scan request"); + rc = p8_pll_utils_poll_sbe(i_target, 1); + if (!rc.ok()) + { + FAPI_ERR("Error from p8_pll_utils_poll_sbe"); + break; + } + + // construct scan request format + ecmdDataBufferBase mbox_data(64); + rc_ecmd |= mbox_data.setBit(MBOX0_REQUEST_VALID_BIT); + rc_ecmd |= mbox_data.insertFromRight(static_cast<uint32_t>(pll_ring_id), + MBOX0_RING_SELECT_START_BIT, + (MBOX0_RING_SELECT_END_BIT- + MBOX0_RING_SELECT_START_BIT+1)); + rc_ecmd |= mbox_data.insertFromRight(static_cast<uint32_t>(i_pll_ring_op), + MBOX0_RING_OP_START_BIT, + (MBOX0_RING_OP_END_BIT- + MBOX0_RING_OP_START_BIT+1)); + rc_ecmd |= mbox_data.insertFromRight(static_cast<uint32_t>(i_pll_bus_id), + MBOX0_RING_BUS_ID_START_BIT, + (MBOX0_RING_BUS_ID_END_BIT- + MBOX0_RING_BUS_ID_START_BIT+1)); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting up SBE MBOX0 data buffer.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + + // submit request to SBE + FAPI_DBG("Submitting scan request to SBE"); + rc = fapiPutScom(i_target, MBOX_SCRATCH_REG0_0x00050038, mbox_data); + if (!rc.ok()) + { + FAPI_ERR("Error writing SBE MBOX0 Register"); + break; + } + + // poll until SBE drops response SBE indicates scan is finished (back to 'ready' state) + // or until maximum poll count is reached + FAPI_DBG("Polling for SBE completion..."); + rc = p8_pll_utils_poll_sbe(i_target, + PROC_A_X_PCI_DMI_PLL_UTILS_SBE_MAX_POLLS); + if (!rc.ok()) + { + FAPI_ERR("Error from p8_pll_utils_poll_sbe"); + break; + } + + // check result of scan operation + FAPI_DBG("SBE reached ready state, checking result of scan operation"); + rc = fapiGetScom(i_target, MBOX_SCRATCH_REG1_0x00050039, mbox_data); + if (!rc.ok()) + { + FAPI_ERR("Error reading SBE MBOX1 Register"); + break; + } + + if (mbox_data.isBitClear(MBOX1_SCAN_REPLY_SUCCESS_BIT)) + { + FAPI_ERR("SBE indicated scan operation failure!"); + const fapi::Target & TARGET = i_target; + const p8_pll_utils_ring_address & PLL_RING_ADDR = i_pll_ring_addr; + const p8_pll_utils_ring_op & PLL_RING_OP = i_pll_ring_op; + const p8_pll_utils_bus_id & PLL_BUS_ID = i_pll_bus_id; + const ecmdDataBufferBase & MBOX1_DATA = mbox_data; + FAPI_SET_HWP_ERROR(rc, RC_P8_PLL_UTILS_SBE_SCAN_ERROR); + break; + } + + FAPI_DBG("SBE reply indicates scan was successful!"); + + } while(0); + + // mark function exit + FAPI_DBG("End"); + return rc; +} + + +//------------------------------------------------------------------------------ +// function: +// Scan PLL boundary ring with setpulse (scan executed by HB/FSP platform) +// +// parameters: i_target => chip target +// i_pll_ring_addr => PLL ring address +// i_pll_ring_op => modification to be made to base PLL content +// i_pll_bus_id => bus instance to target for modification +// returns: FAPI_RC_SUCCESS if operation was successful, else error +//------------------------------------------------------------------------------ +fapi::ReturnCode p8_pll_utils_scan_bndy_non_sbe( + const fapi::Target & i_target, + const p8_pll_utils_ring_address i_pll_ring_addr, + const p8_pll_utils_ring_op i_pll_ring_op, + const p8_pll_utils_bus_id i_pll_bus_id) +{ + // return codes + uint32_t rc_ecmd = 0; + fapi::ReturnCode rc; + + // mark function entry + FAPI_DBG("Start"); + + do + { + // form base chiplet ID / ring data to scan + uint32_t chiplet_base_scom_addr; + ecmdDataBufferBase ring_data; + if (i_pll_ring_addr == RING_ADDRESS_MEMB_TP_BNDY_PLL) + { + chiplet_base_scom_addr = TP_CHIPLET_0x01000000; + rc = p8_pll_utils_calc_memb_tp_bndy_pll(i_target, + i_pll_ring_op, + ring_data); + if (!rc.ok()) + { + FAPI_ERR("Error from p8_pll_utils_calc_memb_tp_bndy_pll"); + break; + } + } + else if (i_pll_ring_addr == RING_ADDRESS_PROC_PB_BNDY_DMIPLL) + { + chiplet_base_scom_addr = NEST_CHIPLET_0x02000000; + rc = p8_pll_utils_calc_proc_pb_bndy_dmipll(i_target, + i_pll_ring_op, + i_pll_bus_id, + ring_data); + if (!rc.ok()) + { + FAPI_ERR("Error from p8_pll_utils_calc_proc_pb_bndy_dmipll"); + break; + } + } + else if (i_pll_ring_addr == RING_ADDRESS_PROC_AB_BNDY_PLL) + { + chiplet_base_scom_addr = A_BUS_CHIPLET_0x08000000; + rc = p8_pll_utils_calc_proc_ab_bndy_pll(i_target, + i_pll_ring_op, + i_pll_bus_id, + ring_data); + if (!rc.ok()) + { + FAPI_ERR("Error from p8_pll_utils_calc_proc_ab_bndy_pll"); + break; + } + } + else + { + chiplet_base_scom_addr = PCIE_CHIPLET_0x09000000; + rc = p8_pll_utils_calc_proc_pci_bndy_pll(i_target, + ring_data); + if (!rc.ok()) + { + FAPI_ERR("Error from p8_pll_utils_calc_proc_pci_bndy_pll"); + break; + } + } + + // configure OPCG to generate setpulse + ecmdDataBufferBase scom_data(64); FAPI_DBG("Writing OPCG Register 0 to generate setpulse ..."); - rc_ecmd |= data.setDoubleWord(0, OPCG_REG0_FOR_SETPULSE); + rc_ecmd |= scom_data.setDoubleWord(0, OPCG_REG0_FOR_SETPULSE); if (rc_ecmd) { FAPI_ERR("Error 0x%x setting up ecmd data buffer to write OPCG Register 0.", rc_ecmd); rc.setEcmdError(rc_ecmd); break; } - rc = fapiPutScom(i_target, i_chiplet_base_scom_addr | GENERIC_OPCG_CNTL0_0x00030002, data); + rc = fapiPutScom(i_target, chiplet_base_scom_addr | GENERIC_OPCG_CNTL0_0x00030002, scom_data); if (!rc.ok()) { FAPI_ERR("Error writing OPCG Register0 to generate setpulse."); @@ -171,14 +980,14 @@ fapi::ReturnCode proc_a_x_pci_dmi_pll_scan_bndy( } FAPI_DBG("Writing OPCG Register 2 to generate setpulse ..."); - rc_ecmd |= data.setDoubleWord(0, OPCG_REG2_FOR_SETPULSE); + rc_ecmd |= scom_data.setDoubleWord(0, OPCG_REG2_FOR_SETPULSE); if (rc_ecmd) { FAPI_ERR("Error 0x%x setting up ecmd data buffer to write OPCG Register 2.", rc_ecmd); rc.setEcmdError(rc_ecmd); break; } - rc = fapiPutScom(i_target, i_chiplet_base_scom_addr | GENERIC_OPCG_CNTL2_0x00030004, data); + rc = fapiPutScom(i_target, chiplet_base_scom_addr | GENERIC_OPCG_CNTL2_0x00030004, scom_data); if (rc) { FAPI_ERR("Error writing OPCG Register2 to generate setpulse."); @@ -186,14 +995,14 @@ fapi::ReturnCode proc_a_x_pci_dmi_pll_scan_bndy( } FAPI_DBG("Writing OPCG Register 3 to generate setpulse ..."); - rc_ecmd |= data.setDoubleWord(0, OPCG_REG3_FOR_SETPULSE); + rc_ecmd |= scom_data.setDoubleWord(0, OPCG_REG3_FOR_SETPULSE); if (rc_ecmd) { FAPI_ERR("Error 0x%x setting up ecmd data buffer to write OPCG Register 3.", rc_ecmd); rc.setEcmdError(rc_ecmd); break; } - rc = fapiPutScom(i_target, i_chiplet_base_scom_addr | GENERIC_OPCG_CNTL3_0x00030005, data); + rc = fapiPutScom(i_target, chiplet_base_scom_addr | GENERIC_OPCG_CNTL3_0x00030005, scom_data); if (rc) { FAPI_ERR("Error writing OPCG Register3 to generate setpulse."); @@ -201,45 +1010,40 @@ fapi::ReturnCode proc_a_x_pci_dmi_pll_scan_bndy( } FAPI_DBG("Writing OPCG Clock Region Register to generate setpulse ..."); - rc_ecmd |= data.setDoubleWord(0, CLK_REGION_FOR_SETPULSE); + rc_ecmd |= scom_data.setDoubleWord(0, CLK_REGION_FOR_SETPULSE); if (rc_ecmd) { FAPI_ERR("Error 0x%x setting up ecmd data buffer to write Clock Region Register.", rc_ecmd); rc.setEcmdError(rc_ecmd); break; } - rc = fapiPutScom(i_target, i_chiplet_base_scom_addr | GENERIC_CLK_REGION_0x00030006, data); + rc = fapiPutScom(i_target, chiplet_base_scom_addr | GENERIC_CLK_REGION_0x00030006, scom_data); if (rc) { FAPI_ERR("Error writing Clock Region Register to generate setpulse."); break; } - //----------------------------------------------------- - // Scan new ring data into boundary scan ring - //----------------------------------------------------- - rc = fapiPutRing(i_target, i_pll_ring_addr, i_pll_ring_data, RING_MODE_SET_PULSE); + // scan new ring data into PLL boundary scan ring + rc = fapiPutRing(i_target, i_pll_ring_addr, ring_data, fapi::RING_MODE_SET_PULSE); if (rc) { - FAPI_ERR("fapiPutRing failed with rc = 0x%x", (uint32_t)rc); + FAPI_ERR("fapiPutRing failed with rc = 0x%x", (uint32_t) rc); break; } FAPI_DBG("Loading of the config bits for PLL is done."); - //----------------------------------------------------- - // Set the OPCG back to a good state - //----------------------------------------------------- - + // set the OPCG back to a good state FAPI_DBG("Writing OPCG Register 3 to clear setpulse ..."); - rc_ecmd |= data.flushTo0(); + rc_ecmd |= scom_data.flushTo0(); if (rc_ecmd) { FAPI_ERR("Error 0x%x setting up ecmd data buffer to clear OPCG Register 3.", rc_ecmd); rc.setEcmdError(rc_ecmd); break; } - rc = fapiPutScom(i_target, i_chiplet_base_scom_addr | GENERIC_OPCG_CNTL3_0x00030005, data); + rc = fapiPutScom(i_target, chiplet_base_scom_addr | GENERIC_OPCG_CNTL3_0x00030005, scom_data); if (rc) { FAPI_ERR("Error writing OPCG Register3 to clear setpulse."); @@ -247,169 +1051,233 @@ fapi::ReturnCode proc_a_x_pci_dmi_pll_scan_bndy( } FAPI_DBG("Writing OPCG Clock Region Register to clear setpulse ..."); - rc_ecmd |= data.flushTo0(); + rc_ecmd |= scom_data.flushTo0(); if (rc_ecmd) { FAPI_ERR("Error 0x%x setting up ecmd data buffer to clear Clock Region Register.", rc_ecmd); rc.setEcmdError(rc_ecmd); break; } - rc = fapiPutScom(i_target, i_chiplet_base_scom_addr | GENERIC_CLK_REGION_0x00030006, data); + rc = fapiPutScom(i_target, chiplet_base_scom_addr | GENERIC_CLK_REGION_0x00030006, scom_data); if (rc) { FAPI_ERR("Error writing Clock Region Register to clear setpulse."); break; } - - //------------------------------------------- - // Clear & Unmask Pervasive LFIR - //------------------------------------------ - - if (i_mask_scan_collision) - { - FAPI_DBG("Clearing Pervasive LFIR scan collision bit ..."); - rc_ecmd |= data.flushTo1(); - rc_ecmd |= data.clearBit(PERV_LFIR_SCAN_COLLISION_BIT); - if (rc_ecmd) - { - FAPI_ERR("Error 0x%x setting up ecmd data buffer to clear Pervasive LFIR Register.", rc_ecmd); - rc.setEcmdError(rc_ecmd); - break; - } - rc = fapiPutScom(i_target, i_chiplet_base_scom_addr | GENERIC_PERV_LFIR_AND_0x0004000B, data); - if (!rc.ok()) - { - FAPI_ERR("Error writing Pervasive LFIR AND Register."); - break; - } - - if (unmask_scan_collision) - { - FAPI_DBG("Unmasking Pervasive LFIR scan collision bit ..."); - rc = fapiPutScom(i_target, i_chiplet_base_scom_addr | GENERIC_PERV_LFIR_MASK_AND_0x0004000E, data); - if (!rc.ok()) - { - FAPI_ERR("Error writing Pervasive LFIR Mask And Register."); - break; - } - } - } } while(0); - - // mark function entry + // mark function exit FAPI_DBG("End"); - return rc; } //------------------------------------------------------------------------------ // function: -// Scan PLL ring to establish runtime state +// Scan PLL boundary ring with setpulse // -// parameters: i_target => chip target -// i_chiplet_base_scom_addr => aligned base address of chiplet SCOM -// address space -// i_pll_ring_addr => PLL ring address -// i_pll_ring_data => data buffer containing full PLL ring -// content -// i_lctank_pll_vco_workaround => enable 2-pass scan workaround for -// lctank PLL vco runaway issue -// i_ccalload_ring_offset => ring offset for ccalload PLL control -// bit (used only if workaround -// is true) -// i_ccalfmin_ring_offset => ring offset for ccalfmin PLL control -// bit (used only if workaround -// is true) +// parameters: i_target => chip target +// i_pll_ring_addr => PLL ring address +// i_pll_ring_op => modification to be made to base PLL content +// i_pll_bus_id => bus instance to target for modification +// i_mask_scan_collision => mask scan collision bit in chiplet +// pervasive LFIR // returns: FAPI_RC_SUCCESS if operation was successful, else error //------------------------------------------------------------------------------ -fapi::ReturnCode proc_a_x_pci_dmi_pll_scan_pll( +fapi::ReturnCode proc_a_x_pci_dmi_pll_scan_bndy( const fapi::Target& i_target, - const uint32_t i_chiplet_base_scom_addr, - const uint32_t i_pll_ring_addr, - ecmdDataBufferBase& i_pll_ring_data, - const bool i_lctank_pll_vco_workaround, - const uint32_t i_ccalload_ring_offset, - const uint32_t i_ccalfmin_ring_offset, + const p8_pll_utils_ring_address i_pll_ring_addr, + const p8_pll_utils_ring_op i_pll_ring_op, + const p8_pll_utils_bus_id i_pll_bus_id, const bool i_mask_scan_collision) { // return codes - uint32_t rc_ecmd = 0; fapi::ReturnCode rc; - uint8_t scan_count = 1; + uint32_t rc_ecmd = 0; // mark function entry FAPI_DBG("Start"); do { - // modify ring for first scan if workaround is engaged - if (i_lctank_pll_vco_workaround) + // check validity of arguments + bool invalid_ring_address = ((i_pll_ring_addr != RING_ADDRESS_MEMB_TP_BNDY_PLL) && + (i_pll_ring_addr != RING_ADDRESS_PROC_PB_BNDY_DMIPLL) && + (i_pll_ring_addr != RING_ADDRESS_PROC_AB_BNDY_PLL) && + (i_pll_ring_addr != RING_ADDRESS_PROC_PCI_BNDY_PLL)); + bool invalid_ring_op = (((i_pll_ring_op != RING_OP_BASE) && + (i_pll_ring_op != RING_OP_MOD_VCO_S1) && + (i_pll_ring_op != RING_OP_MOD_VCO_S2) && + (i_pll_ring_op != RING_OP_MOD_REFCLK_SEL) && + (i_pll_ring_op != RING_OP_MOD_PFD360)) || + ((i_pll_ring_addr == RING_ADDRESS_MEMB_TP_BNDY_PLL) && + ((i_pll_ring_op == RING_OP_MOD_VCO_S1) || + (i_pll_ring_op == RING_OP_MOD_VCO_S2))) || + ((i_pll_ring_addr == RING_ADDRESS_PROC_PCI_BNDY_PLL) && + (i_pll_ring_op != RING_OP_BASE))); + bool invalid_bus_id = ((((i_pll_ring_addr == RING_ADDRESS_MEMB_TP_BNDY_PLL) || + (i_pll_ring_addr == RING_ADDRESS_PROC_PCI_BNDY_PLL)) && + (i_pll_bus_id != RING_BUS_ID_0)) || + (((i_pll_ring_op == RING_OP_BASE) || + (i_pll_ring_op == RING_OP_MOD_VCO_S1) || + (i_pll_ring_op == RING_OP_MOD_VCO_S2)) && + (i_pll_bus_id != RING_BUS_ID_0)) || + ((i_pll_ring_addr == RING_ADDRESS_PROC_AB_BNDY_PLL) && + (i_pll_bus_id != RING_BUS_ID_0) && + (i_pll_bus_id != RING_BUS_ID_1) && + (i_pll_bus_id != RING_BUS_ID_2) && + (i_pll_bus_id != RING_BUS_ID_3)) || + ((i_pll_ring_addr == RING_ADDRESS_PROC_PB_BNDY_DMIPLL) && + (i_pll_bus_id != RING_BUS_ID_0) && + (i_pll_bus_id != RING_BUS_ID_1) && + (i_pll_bus_id != RING_BUS_ID_2) && + (i_pll_bus_id != RING_BUS_ID_3) && + (i_pll_bus_id != RING_BUS_ID_4) && + (i_pll_bus_id != RING_BUS_ID_5) && + (i_pll_bus_id != RING_BUS_ID_6) && + (i_pll_bus_id != RING_BUS_ID_7))); + + if (invalid_ring_address || + invalid_ring_op || + invalid_bus_id) + { + FAPI_ERR("Invalid/unsupported ring operation requested"); + FAPI_ERR(" ring address: %x (invalid = %d)", i_pll_ring_addr, invalid_ring_address); + FAPI_ERR(" ring op: %x (invalid = %d)", i_pll_ring_op, invalid_ring_op); + FAPI_ERR(" bus id: %x (invalid = %d)", i_pll_bus_id, invalid_bus_id); + + const fapi::Target & TARGET = i_target; + const p8_pll_utils_ring_address & PLL_RING_ADDR = i_pll_ring_addr; + const p8_pll_utils_ring_op & PLL_RING_OP = i_pll_ring_op; + const p8_pll_utils_bus_id & PLL_BUS_ID = i_pll_bus_id; + const bool & INVALID_RING_ADDRESS = invalid_ring_address; + const bool & INVALID_RING_OP = invalid_ring_op; + const bool & INVALID_BUS_ID = invalid_bus_id; + FAPI_SET_HWP_ERROR(rc, RC_P8_PLL_UTILS_INVALID_OPERATION); + break; + } + + // optionally mask pervasive LFIR prior to scan operation + bool unmask_scan_collision = false; + uint32_t chiplet_base_scom_addr; + ecmdDataBufferBase scom_data(64); + if (i_pll_ring_addr == RING_ADDRESS_MEMB_TP_BNDY_PLL) + { + chiplet_base_scom_addr = TP_CHIPLET_0x01000000; + } + else if (i_pll_ring_addr == RING_ADDRESS_PROC_PB_BNDY_DMIPLL) + { + chiplet_base_scom_addr = NEST_CHIPLET_0x02000000; + } + else if (i_pll_ring_addr == RING_ADDRESS_PROC_AB_BNDY_PLL) + { + chiplet_base_scom_addr = A_BUS_CHIPLET_0x08000000; + } + else { - rc_ecmd |= i_pll_ring_data.setBit(i_ccalload_ring_offset); - rc_ecmd |= i_pll_ring_data.setBit(i_ccalfmin_ring_offset); + chiplet_base_scom_addr = PCIE_CHIPLET_0x09000000; + } + + if (i_mask_scan_collision) + { + FAPI_DBG("Reading value of Pervasive LFIR scan collision mask bit ..."); + rc = fapiGetScom(i_target, chiplet_base_scom_addr | GENERIC_PERV_LFIR_MASK_0x0004000D, scom_data); + if (!rc.ok()) + { + FAPI_ERR("Error reading Pervasive LFIR Mask OR Register."); + break; + } + unmask_scan_collision = scom_data.isBitClear(PERV_LFIR_SCAN_COLLISION_BIT); + + FAPI_DBG("Masking Pervasive LFIR scan collision bit ..."); + rc_ecmd |= scom_data.flushTo0(); + rc_ecmd |= scom_data.setBit(PERV_LFIR_SCAN_COLLISION_BIT); if (rc_ecmd) { - FAPI_ERR("Error 0x%x setting up data buffer to enable lctank PLL vco workaround (scan = %d)", rc_ecmd, scan_count); + FAPI_ERR("Error 0x%x setting up ecmd data buffer to set Pervasive LFIR Mask Register.", rc_ecmd); rc.setEcmdError(rc_ecmd); break; } + rc = fapiPutScom(i_target, chiplet_base_scom_addr | GENERIC_PERV_LFIR_MASK_OR_0x0004000F, scom_data); + if (!rc.ok()) + { + FAPI_ERR("Error writing Pervasive LFIR Mask OR Register."); + break; + } } - // scan with setpulse - rc = proc_a_x_pci_dmi_pll_scan_bndy( - i_target, - i_chiplet_base_scom_addr, - i_pll_ring_addr, - i_pll_ring_data, - i_mask_scan_collision); + // make determination of scan path to use + bool use_sbe; + FAPI_EXEC_HWP(rc, proc_use_sbe_scan_service, i_target, use_sbe); if (!rc.ok()) { - FAPI_ERR("Error from proc_a_x_pci_dmi_pll_scan_bndy (scan = %d)", scan_count); + FAPI_ERR("Error from proc_use_sbe_scan_service"); break; } - scan_count++; - // release PLL & re-scan if workaround is engaged - if (i_lctank_pll_vco_workaround) + // scan path determined + // request SCAN via SBE (SBE holds data) + if (use_sbe) { - rc = proc_a_x_pci_dmi_pll_release_pll( - i_target, - i_chiplet_base_scom_addr, - false); + rc = p8_pll_utils_scan_bndy_sbe(i_target, + i_pll_ring_addr, + i_pll_ring_op, + i_pll_bus_id); if (!rc.ok()) { - FAPI_ERR("Error from proc_a_x_pci_dmi_pll_release_pll"); + FAPI_ERR("Error from p8_pll_utils_scan_bndy_sbe"); break; } + } + // construct ring content to scan via attributes, invoke FAPI API + else + { + rc = p8_pll_utils_scan_bndy_non_sbe(i_target, + i_pll_ring_addr, + i_pll_ring_op, + i_pll_bus_id); + if (!rc.ok()) + { + FAPI_ERR("Error from p8_pll_utils_scan_bndy_non_sbe"); + break; + } + } - rc_ecmd |= i_pll_ring_data.setBit(i_ccalload_ring_offset); - rc_ecmd |= i_pll_ring_data.clearBit(i_ccalfmin_ring_offset); + // clear & Unmask Pervasive LFIR + if (i_mask_scan_collision) + { + FAPI_DBG("Clearing Pervasive LFIR scan collision bit ..."); + rc_ecmd |= scom_data.flushTo1(); + rc_ecmd |= scom_data.clearBit(PERV_LFIR_SCAN_COLLISION_BIT); if (rc_ecmd) { - FAPI_ERR("Error 0x%x setting up data buffer to enable lctank PLL vco workaround (scan = %d)", rc_ecmd, scan_count); + FAPI_ERR("Error 0x%x setting up ecmd data buffer to clear Pervasive LFIR Register.", rc_ecmd); rc.setEcmdError(rc_ecmd); break; } - - // scan with setpulse - rc = proc_a_x_pci_dmi_pll_scan_bndy( - i_target, - i_chiplet_base_scom_addr, - i_pll_ring_addr, - i_pll_ring_data, - i_mask_scan_collision); + rc = fapiPutScom(i_target, chiplet_base_scom_addr | GENERIC_PERV_LFIR_AND_0x0004000B, scom_data); if (!rc.ok()) { - FAPI_ERR("Error from proc_a_x_pci_dmi_pll_scan_bndy (scan = %d)", scan_count); + FAPI_ERR("Error writing Pervasive LFIR AND Register."); break; } + + if (unmask_scan_collision) + { + FAPI_DBG("Unmasking Pervasive LFIR scan collision bit ..."); + rc = fapiPutScom(i_target, chiplet_base_scom_addr | GENERIC_PERV_LFIR_MASK_AND_0x0004000E, scom_data); + if (!rc.ok()) + { + FAPI_ERR("Error writing Pervasive LFIR Mask And Register."); + break; + } + } } + } while(0); - // mark function entry + // mark function exit FAPI_DBG("End"); return rc; @@ -439,7 +1307,7 @@ fapi::ReturnCode proc_a_x_pci_dmi_pll_release_pll( fapi::ReturnCode rc; // mark function entry - FAPI_DBG("Start proc_a_x_pci_dmi_pll_release_pll"); + FAPI_DBG("Start"); do { @@ -556,7 +1424,7 @@ fapi::ReturnCode proc_a_x_pci_dmi_pll_release_pll( } while(0); // mark function entry - FAPI_DBG("End proc_a_x_pci_dmi_pll_release_pll"); + FAPI_DBG("End"); return rc; } diff --git a/src/usr/hwpf/hwp/nest_chiplets/proc_a_x_pci_dmi_pll_setup/proc_a_x_pci_dmi_pll_utils.H b/src/usr/hwpf/hwp/nest_chiplets/proc_a_x_pci_dmi_pll_setup/proc_a_x_pci_dmi_pll_utils.H index 8e9610119..c1a16c4de 100644 --- a/src/usr/hwpf/hwp/nest_chiplets/proc_a_x_pci_dmi_pll_setup/proc_a_x_pci_dmi_pll_utils.H +++ b/src/usr/hwpf/hwp/nest_chiplets/proc_a_x_pci_dmi_pll_setup/proc_a_x_pci_dmi_pll_utils.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2013,2014 */ +/* Contributors Listed Below - COPYRIGHT 2013,2015 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -22,18 +22,18 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: proc_a_x_pci_dmi_pll_utils.H,v 1.3 2013/12/10 02:50:34 mfred Exp $ +// $Id: proc_a_x_pci_dmi_pll_utils.H,v 1.4 2015/05/14 21:18:32 jmcgill Exp $ // $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/proc_a_x_pci_dmi_pll_utils.H,v $ //------------------------------------------------------------------------------ // *| -// *! (C) Copyright International Business Machines Corp. 2012 +// *! (C) Copyright International Business Machines Corp. 2015 // *! All Rights Reserved -- Property of IBM // *! *** *** // *| // *! TITLE : proc_a_x_pci_dmi_pll_utils.H -// *! DESCRIPTION : A/X/PCI/DMI PLL utility functions +// *! DESCRIPTION : PLL configuration utility functions // *! -// *! OWNER NAME : Ralph Koester Email: rkoester@de.ibm.com +// *! OWNER NAME : Joe McGill Email: jmcgill@us.ibm.com // *! //------------------------------------------------------------------------------ @@ -43,30 +43,47 @@ //------------------------------------------------------------------------------ // Includes //------------------------------------------------------------------------------ - #include <fapi.H> //------------------------------------------------------------------------------ // Constant definitions //------------------------------------------------------------------------------ +enum p8_pll_utils_ring_address +{ + RING_ADDRESS_MEMB_TP_BNDY_PLL = 0x01030088, + RING_ADDRESS_PROC_AB_BNDY_PLL = 0x08030088, + RING_ADDRESS_PROC_PCI_BNDY_PLL = 0x09030088, + RING_ADDRESS_PROC_PB_BNDY_DMIPLL = 0x02030088 +}; -const uint32_t TP_BNDY_PLL_RING_ADDR = 0x00030088; -const uint32_t MEMB_TP_BNDY_PLL_RING_ADDR = 0x01030088; -const uint32_t PB_BNDY_DMIPLL_RING_ADDR = 0x02030088; -const uint32_t AB_BNDY_PLL_RING_ADDR = 0x08030088; -const uint32_t PCI_BNDY_PLL_RING_ADDR = 0x09030088; - -const uint32_t DMI_PLL_VCO_WORKAROUND_THRESHOLD_FREQ = 4800; - -const uint32_t PB_BNDY_DMIPLL_RING_CCALLOAD_OFFSET = 580; -const uint32_t PB_BNDY_DMIPLL_RING_CCALFMIN_OFFSET = 581; - -const uint32_t AB_BNDY_PLL_RING_CCALLOAD_OFFSET = 278; -const uint32_t AB_BNDY_PLL_RING_CCALFMIN_OFFSET = 279; +enum p8_pll_utils_ring_id +{ + RING_ID_ABUS = 1, + RING_ID_PCI = 2, + RING_ID_DMI = 3 +}; -const uint32_t PCI_BNDY_PLL_RING_CCALLOAD_OFFSET = 0x0; -const uint32_t PCI_BNDY_PLL_RING_CCALFMIN_OFFSET = 0x0; +enum p8_pll_utils_ring_op +{ + RING_OP_BASE = 0, + RING_OP_MOD_VCO_S1 = 1, + RING_OP_MOD_VCO_S2 = 2, + RING_OP_MOD_REFCLK_SEL = 3, + RING_OP_MOD_PFD360 = 4 +}; + +enum p8_pll_utils_bus_id +{ + RING_BUS_ID_0 = 0, + RING_BUS_ID_1 = 1, + RING_BUS_ID_2 = 2, + RING_BUS_ID_3 = 3, + RING_BUS_ID_4 = 4, + RING_BUS_ID_5 = 5, + RING_BUS_ID_6 = 6, + RING_BUS_ID_7 = 7 +}; //------------------------------------------------------------------------------ @@ -76,67 +93,33 @@ const uint32_t PCI_BNDY_PLL_RING_CCALFMIN_OFFSET = 0x0; extern "C" { - //------------------------------------------------------------------------------ // function: // Scan PLL boundary ring with setpulse // -// parameters: i_target => chip target -// i_chiplet_base_scom_addr => aligned base address of chiplet SCOM -// address space -// i_pll_ring_addr => PLL ring address -// i_pll_ring_data => data buffer containing full PLL ring -// content -// i_mask_scan_collision => mask scan collision bit in chiplet -// pervasive LFIR +// parameters: i_target => chip target +// i_pll_ring_addr => PLL ring address +// i_pll_ring_op => modification to be made to base PLL content +// i_pll_bus_id => bus instance to target for modification +// i_mask_scan_collision => mask scan collision bit in chiplet +// pervasive LFIR // returns: FAPI_RC_SUCCESS if operation was successful, else error //------------------------------------------------------------------------------ fapi::ReturnCode proc_a_x_pci_dmi_pll_scan_bndy( const fapi::Target& i_target, - const uint32_t i_chiplet_base_scom_addr, - const uint32_t i_pll_ring_addr, - ecmdDataBufferBase& i_pll_ring_data, - const bool i_mask_scan_collision); - - -//------------------------------------------------------------------------------ -// function: -// Scan PLL ring to establish runtime state -// -// parameters: i_target => chip target -// i_chiplet_base_scom_addr => aligned base address of chiplet SCOM -// address space -// i_pll_ring_addr => PLL ring address -// i_pll_ring_data => data buffer containing full PLL ring -// content -// i_lctank_pll_vco_workaround => enable 2-pass scan workaround for -// lctank PLL vco runaway issue -// i_ccalload_ring_offset => ring offset for ccalload PLL control -// bit (used only if workaround -// is true) -// i_ccalfmin_ring_offset => ring offset for ccalfmin PLL control -// bit (used only if workaround -// is true) -// i_mask_scan_collision => mask scan collision bit in chiplet -// pervasive LFIR -// returns: FAPI_RC_SUCCESS if operation was successful, else error -//------------------------------------------------------------------------------ -fapi::ReturnCode proc_a_x_pci_dmi_pll_scan_pll( - const fapi::Target& i_target, - const uint32_t i_chiplet_base_scom_addr, - const uint32_t i_pll_ring_addr, - ecmdDataBufferBase& i_pll_ring_data, - const bool i_lctank_pll_vco_workaround, - const uint32_t i_ccalload_ring_offset, - const uint32_t i_ccalfmin_ring_offset, + const p8_pll_utils_ring_address i_pll_ring_addr, + const p8_pll_utils_ring_op i_pll_ring_op, + const p8_pll_utils_bus_id i_pll_bus_id, const bool i_mask_scan_collision); //------------------------------------------------------------------------------ // function: -// Release PLL from test mode/bypass/reset and optionally check for lock +// Release chiplet PLL from test mode/bypass/reset and optionally check +// for lock // // parameters: i_target => chip target +// // i_chiplet_base_scom_addr => aligned base address of chiplet SCOM // address space // i_check_lock => check for PLL lock? diff --git a/src/usr/hwpf/hwp/nest_chiplets/proc_start_clocks_chiplets/proc_start_clocks_chiplets.C b/src/usr/hwpf/hwp/nest_chiplets/proc_start_clocks_chiplets/proc_start_clocks_chiplets.C index 4751c0156..025c3d0c9 100644 --- a/src/usr/hwpf/hwp/nest_chiplets/proc_start_clocks_chiplets/proc_start_clocks_chiplets.C +++ b/src/usr/hwpf/hwp/nest_chiplets/proc_start_clocks_chiplets/proc_start_clocks_chiplets.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2012,2014 */ +/* Contributors Listed Below - COPYRIGHT 2012,2015 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -22,7 +22,7 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: proc_start_clocks_chiplets.C,v 1.18 2014/09/26 19:00:42 jmcgill Exp $ +// $Id: proc_start_clocks_chiplets.C,v 1.19 2015/05/14 21:21:34 jmcgill Exp $ // $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/proc_start_clocks_chiplets.C,v $ //------------------------------------------------------------------------------ // *| @@ -194,42 +194,6 @@ fapi::ReturnCode proc_start_clocks_chiplet_set_mux_selects( //------------------------------------------------------------------------------ -// function: utility subroutine to clear scan select register -// parameters: i_target => chip target -// i_chiplet_base_addr => base SCOM address for chiplet -// returns: FAPI_RC_SUCCESS if operation was successful, else error -//------------------------------------------------------------------------------ -fapi::ReturnCode proc_start_clocks_chiplet_clear_clk_scansel_reg( - const fapi::Target& i_target, - const uint32_t i_chiplet_base_addr) -{ - fapi::ReturnCode rc; - ecmdDataBufferBase zero_data(64); - uint32_t scom_addr = i_chiplet_base_addr | - GENERIC_CLK_SCANSEL_0x00030007; - - FAPI_DBG("proc_start_clocks_chiplet_clear_clk_scansel_reg: Start"); - - do - { - // clear chiplet scan select register - rc = fapiPutScom(i_target, scom_addr, zero_data); - if (rc) - { - FAPI_ERR("proc_start_clocks_chiplet_clear_clk_scansel_reg: fapiPutScom error (CLK_SCANSEL_0x%08X)", - scom_addr); - break; - } - - } while(0); - - FAPI_DBG("proc_start_clocks_chiplet_clear_clk_scansel_reg: End"); - - return rc; -} - - -//------------------------------------------------------------------------------ // function: utility subroutine to get partial good vector from SEEPROM // parameters: i_target => chip target // i_chiplet_base_addr => base SCOM address for chiplet @@ -732,16 +696,6 @@ fapi::ReturnCode proc_start_clocks_generic_chiplet( break; } - // clear clock scansel register - FAPI_DBG("Clearing clock scansel register ..."); - rc = proc_start_clocks_chiplet_clear_clk_scansel_reg(i_target, - i_chiplet_base_addr); - if (rc) - { - FAPI_ERR("proc_start_clocks_generic_chiplet: Error clearing clock scansel register"); - break; - } - // pick partial good region vector from SEEPROM FAPI_DBG("Get partial good region vector ..."); rc = proc_start_clocks_get_partial_good_vector(i_target, diff --git a/src/usr/hwpf/hwp/secure_boot/makefile b/src/usr/hwpf/hwp/secure_boot/makefile new file mode 100644 index 000000000..f010e90c7 --- /dev/null +++ b/src/usr/hwpf/hwp/secure_boot/makefile @@ -0,0 +1,52 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/usr/hwpf/hwp/secure_boot/makefile $ +# +# OpenPOWER HostBoot Project +# +# Contributors Listed Below - COPYRIGHT 2015 +# [+] International Business Machines Corp. +# +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# IBM_PROLOG_END_TAG + +ROOTPATH = ../../../../.. + +MODULE = secure_boot + +## support for Targeting and fapi +EXTRAINCDIR += ${ROOTPATH}/src/include/usr/ecmddatabuffer +EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/fapi +EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/plat +EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/hwp +## pointer to common HWP files +EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/include + +## Include sub dirs +## NOTE: add a new EXTRAINCDIR when you add a new HWP +EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/secure_boot +EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/slave_sbe/proc_cen_ref_clk_enable +EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/slave_sbe/proc_check_slave_sbe_seeprom_complete +EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/core_activate/proc_stop_deadman_timer + +OBJS += proc_check_security.o +OBJS += proc_stop_sbe_scan_service.o +OBJS += proc_use_sbe_scan_service.o + +## NOTE: add a new directory onto the vpaths when you add a new HWP +VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/secure_boot + +include ${ROOTPATH}/config.mk diff --git a/src/usr/hwpf/hwp/secure_boot/proc_check_security.C b/src/usr/hwpf/hwp/secure_boot/proc_check_security.C new file mode 100644 index 000000000..9514ef4b7 --- /dev/null +++ b/src/usr/hwpf/hwp/secure_boot/proc_check_security.C @@ -0,0 +1,100 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/secure_boot/proc_check_security.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: proc_check_security.C,v 1.2 2015/08/03 14:04:43 thi Exp $ +// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/proc_check_security.C,v $ +//------------------------------------------------------------------------------ +// *| +// *! (C) Copyright International Business Machines Corp. 2015 +// *! All Rights Reserved -- Property of IBM +// *! *** *** +// *| +// *! TITLE : proc_check_security.C +// *! DESCRIPTION : Determine state of processor security controls +// *! +// *! OWNER NAME : Joe McGill Email: jmcgill@us.ibm.com +// *! +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ +// Includes +//------------------------------------------------------------------------------ +#include <p8_scom_addresses.H> +#include <proc_check_security.H> + + +//------------------------------------------------------------------------------ +// Constant definitions +//------------------------------------------------------------------------------ + +// Security Switch register field/bit definitions +const uint32_t OTPC_M_SECURITY_SWITCH_TRUSTED_BOOT_BIT = 1; + + +//------------------------------------------------------------------------------ +// Function definitions +//------------------------------------------------------------------------------ + +extern "C" +{ + +//------------------------------------------------------------------------------ +// function: +// Determine state of processor security controls +// +// parameters: i_target => chip target +// o_secure => true if security enabled, else false +// returns: FAPI_RC_SUCCESS if operation was successful, else error +//------------------------------------------------------------------------------ +fapi::ReturnCode proc_check_security( + const fapi::Target& i_target, + bool & o_secure) +{ + // return codes + fapi::ReturnCode rc; + + // mark function entry + FAPI_DBG("Start"); + + do + { + ecmdDataBufferBase security_switch_data(64); + rc = fapiGetScom(i_target, OTPC_M_SECURITY_SWITCH_0x00010005, security_switch_data); + if (!rc.ok()) + { + FAPI_ERR("Error reading Security Switch Register"); + break; + } + o_secure = security_switch_data.isBitSet(OTPC_M_SECURITY_SWITCH_TRUSTED_BOOT_BIT); + + } while(0); + + // mark function entry + FAPI_DBG("End"); + return rc; +} + + +} // extern "C" diff --git a/src/usr/hwpf/hwp/secure_boot/proc_check_security.H b/src/usr/hwpf/hwp/secure_boot/proc_check_security.H new file mode 100644 index 000000000..8cad2b975 --- /dev/null +++ b/src/usr/hwpf/hwp/secure_boot/proc_check_security.H @@ -0,0 +1,79 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/secure_boot/proc_check_security.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: proc_check_security.H,v 1.1 2015/05/14 21:16:40 jmcgill Exp $ +// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/proc_check_security.H,v $ +//------------------------------------------------------------------------------ +// *| +// *! (C) Copyright International Business Machines Corp. 2015 +// *! All Rights Reserved -- Property of IBM +// *! *** *** +// *| +// *! TITLE : proc_check_security.H +// *! DESCRIPTION : Determine state of processor security controls +// *! +// *! OWNER NAME : Joe McGill Email: jmcgill@us.ibm.com +// *! +//------------------------------------------------------------------------------ + +#ifndef _PROC_CHECK_SECURITY_H_ +#define _PROC_CHECK_SECURITY_H_ + +//------------------------------------------------------------------------------ +// Includes +//------------------------------------------------------------------------------ +#include <fapi.H> + + +//------------------------------------------------------------------------------ +// Function prototypes +//------------------------------------------------------------------------------ + +// function pointer typedef definition for HWP call support +typedef fapi::ReturnCode (*proc_check_security_FP_t)(const fapi::Target &, bool &); + + +//------------------------------------------------------------------------------ +// Function prototypes +//------------------------------------------------------------------------------ + +extern "C" +{ + +//------------------------------------------------------------------------------ +// function: +// Determine state of processor security controls +// +// parameters: i_target => chip target +// o_secure => true if security enabled, else false +// returns: FAPI_RC_SUCCESS if operation was successful, else error +//------------------------------------------------------------------------------ +fapi::ReturnCode proc_check_security( + const fapi::Target& i_target, + bool & o_secure); + + +} // extern "C" + +#endif // _PROC_CHECK_SECURITY_H_ diff --git a/src/usr/hwpf/hwp/secure_boot/proc_sbe_scan_service.H b/src/usr/hwpf/hwp/secure_boot/proc_sbe_scan_service.H new file mode 100644 index 000000000..cb5a88027 --- /dev/null +++ b/src/usr/hwpf/hwp/secure_boot/proc_sbe_scan_service.H @@ -0,0 +1,49 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/secure_boot/proc_sbe_scan_service.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: proc_sbe_scan_service.H,v 1.1 2015/05/14 22:23:55 jmcgill Exp $ + +/// Substep numbers for the proc_sbe_scan_service procedure + +#ifndef __PROC_SBE_SCAN_SERVICE_H +#define __PROC_SBE_SCAN_SERVICE_H + +#include "fapi_sbe_common.H" +#include "sbe_vital.H" + +//NOTE: The following values must stay constant as HB looks for them +CONST_UINT8_T(SUBSTEP_PROC_ENTRY, ULL(0x0)); +CONST_UINT8_T(SUBSTEP_SBE_READY, ULL(0x1)); +CONST_UINT8_T(SUBSTEP_DECODE_REQ, ULL(0x2)); +CONST_UINT8_T(SUBSTEP_SCAN_IP, ULL(0x3)); +CONST_UINT8_T(SUBSTEP_SCAN_PRE_BRANCH, ULL(0x4)); +CONST_UINT8_T(SUBSTEP_SCAN_IN_BRANCH, ULL(0x5)); +CONST_UINT8_T(SUBSTEP_SCAN_DONE, ULL(0x6)); +CONST_UINT8_T(SUBSTEP_SCAN_POST_BRANCH, ULL(0x7)); +CONST_UINT8_T(SUBSTEP_RESCAN_IP, ULL(0x8)); +CONST_UINT8_T(SUBSTEP_RESCAN_CHECKWORD_ERR, ULL(0xD)); +CONST_UINT8_T(SUBSTEP_ARG_ERR, ULL(0xE)); +CONST_UINT8_T(SUBSTEP_HALT_SUCCESS, ULL(0xF)); + +#endif // __PROC_SBE_SCAN_SERVICE_H diff --git a/src/usr/hwpf/hwp/secure_boot/proc_sbe_scan_service_errors.xml b/src/usr/hwpf/hwp/secure_boot/proc_sbe_scan_service_errors.xml new file mode 100644 index 000000000..812cb87a6 --- /dev/null +++ b/src/usr/hwpf/hwp/secure_boot/proc_sbe_scan_service_errors.xml @@ -0,0 +1,52 @@ +<!-- IBM_PROLOG_BEGIN_TAG --> +<!-- This is an automatically generated prolog. --> +<!-- --> +<!-- $Source: src/usr/hwpf/hwp/secure_boot/proc_sbe_scan_service_errors.xml $ --> +<!-- --> +<!-- OpenPOWER HostBoot Project --> +<!-- --> +<!-- Contributors Listed Below - COPYRIGHT 2015 --> +<!-- [+] International Business Machines Corp. --> +<!-- --> +<!-- --> +<!-- Licensed under the Apache License, Version 2.0 (the "License"); --> +<!-- you may not use this file except in compliance with the License. --> +<!-- You may obtain a copy of the License at --> +<!-- --> +<!-- http://www.apache.org/licenses/LICENSE-2.0 --> +<!-- --> +<!-- Unless required by applicable law or agreed to in writing, software --> +<!-- distributed under the License is distributed on an "AS IS" BASIS, --> +<!-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or --> +<!-- implied. See the License for the specific language governing --> +<!-- permissions and limitations under the License. --> +<!-- --> +<!-- IBM_PROLOG_END_TAG --> +<!-- $Id: proc_sbe_scan_service_errors.xml,v 1.2 2015/05/15 15:25:36 jmcgill Exp $ --> +<!-- Halt codes for proc_sbe_scan_service --> +<hwpErrors> + <!-- ******************************************************************** --> + <hwpError> + <rc>RC_PROC_SBE_SCAN_SERVICE_INVALID_OPERATION</rc> + <description> + Procedure: proc_sbe_scan_service + Invalid PLL configuration requested by caller. + </description> + <sbeError/> + <collectRegisterFfdc> + <id>REG_FFDC_SBE_SCAN_SERVICE</id> + <target>CHIP</target> + </collectRegisterFfdc> + <callout> + <procedure>CODE</procedure> + <priority>HIGH</priority> + </callout> + </hwpError> + <!-- ******************************************************************** --> + <registerFfdc> + <id>REG_FFDC_SBE_SCAN_SERVICE</id> + <scomRegister>MBOX_SCRATCH_REG0_0x00050038</scomRegister> + <scomRegister>MBOX_SCRATCH_REG1_0x00050039</scomRegister> + </registerFfdc> + <!-- ******************************************************************** --> +</hwpErrors> diff --git a/src/usr/hwpf/hwp/secure_boot/proc_stop_sbe_scan_service.C b/src/usr/hwpf/hwp/secure_boot/proc_stop_sbe_scan_service.C new file mode 100644 index 000000000..bedad0b7e --- /dev/null +++ b/src/usr/hwpf/hwp/secure_boot/proc_stop_sbe_scan_service.C @@ -0,0 +1,295 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/secure_boot/proc_stop_sbe_scan_service.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: proc_stop_sbe_scan_service.C,v 1.2 2015/07/27 00:48:38 jmcgill Exp $ +// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/proc_stop_sbe_scan_service.C,v $ +//------------------------------------------------------------------------------ +// *| +// *! (C) Copyright International Business Machines Corp. 2015 +// *! All Rights Reserved -- Property of IBM +// *! *** *** +// *| +// *! TITLE : proc_stop_sbe_scan_service.C +// *! DESCRIPTION : Stop SBE runtime scan service +// *! +// *! OWNER NAME : Joe McGill Email: jmcgill@us.ibm.com +// *! +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ +// Includes +//------------------------------------------------------------------------------ +#include <proc_stop_sbe_scan_service.H> +#include <p8_scom_addresses.H> +#include <p8_istep_num.H> +#include <proc_sbe_scan_service.H> +#include <proc_use_sbe_scan_service.H> +#include <proc_extract_sbe_rc.H> +#include <proc_reset_i2cm_bus_fence.H> +#include <proc_sbe_utils.H> + + +//------------------------------------------------------------------------------ +// Constant definitions +//------------------------------------------------------------------------------ + +// SBE progress constants +const uint8_t SBE_EXIT_SUCCESS_0xF = 0xF; + +// SBE polling constants +const uint32_t SBE_HALT_POLL_MAX_LOOPS = 10; +const uint32_t SBE_HALT_POLL_DELAY_HW = 2000000; +const uint32_t SBE_HALT_POLL_DELAY_SIM = 10000000; + +// SBE Mailbox0 Register scan request format constants +const uint32_t MBOX0_REQUEST_VALID_BIT = 0; +const uint32_t MBOX0_HALT_PATTERN_START_BIT = 16; +const uint32_t MBOX0_HALT_PATTERN_END_BIT = 31; +const uint32_t MBOX0_HALT_PATTERN = 0xD05E; + +//------------------------------------------------------------------------------ +// Function definitions +//------------------------------------------------------------------------------ + +extern "C" +{ + +//------------------------------------------------------------------------------ +// function: +// Stop SBE runtime scan service +// +// parameters: i_target => chip target +// returns: FAPI_RC_SUCCESS if operation was successful, else error +//------------------------------------------------------------------------------ +fapi::ReturnCode proc_stop_sbe_scan_service( + const fapi::Target& i_target, + const void* i_pSEEPROM) +{ + // return codes + fapi::ReturnCode rc; + uint32_t rc_ecmd = 0; + + // track if procedure has cleared I2C master bus fence + bool i2cm_bus_fence_cleared = false; + + // mark function entry + FAPI_DBG("Start"); + + do + { + // check SBE progress + bool sbe_running = true; + size_t loop_time = 0; + uint8_t halt_code = 0; + uint16_t istep_num = 0; + uint8_t substep_num = 0; + bool scan_service_loop_reached = false; + + // retrieve status + rc = proc_sbe_utils_check_status( + i_target, + sbe_running, + halt_code, + istep_num, + substep_num); + if (!rc.ok()) + { + FAPI_ERR("Error from proc_check_sbe_state_check_status"); + break; + } + + // get HB->SBE request mailbox, check that it is clear + ecmdDataBufferBase mbox_data(64); + bool sbe_ready = false; + rc = fapiGetScom(i_target, MBOX_SCRATCH_REG0_0x00050038, mbox_data); + if (!rc.ok()) + { + FAPI_ERR("Scom error reading SBE MBOX0 Register"); + break; + } + sbe_ready = (mbox_data.getDoubleWord(0) == 0); + + scan_service_loop_reached = + sbe_running && + sbe_ready && + !halt_code && + (istep_num == PROC_SBE_SCAN_SERVICE_ISTEP_NUM) && + (substep_num == SUBSTEP_SBE_READY); + + FAPI_INF("SBE is running [%d], loop time [%zd], scan service loop reached [%d]", + sbe_running, loop_time, scan_service_loop_reached); + + if (!sbe_running) + { + FAPI_INF("SBE is stopped, exiting!"); + break; + } + else if (scan_service_loop_reached) + { + // format stop request + rc_ecmd |= mbox_data.setBit(MBOX0_REQUEST_VALID_BIT); + rc_ecmd |= mbox_data.insertFromRight(MBOX0_HALT_PATTERN, + MBOX0_HALT_PATTERN_START_BIT, + (MBOX0_HALT_PATTERN_END_BIT- + MBOX0_HALT_PATTERN_START_BIT)+1); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting up SBE MBOX0 data buffer.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + + // submit stop request to SBE + FAPI_DBG("Submitting stop request to SBE"); + rc = fapiPutScom(i_target, MBOX_SCRATCH_REG0_0x00050038, mbox_data); + if (!rc.ok()) + { + FAPI_ERR("Error writing SBE MBOX0 Register"); + break; + } + + // pause to allow request to be processed + uint32_t loop_num = 0; + while (sbe_running && (loop_num < SBE_HALT_POLL_MAX_LOOPS)) + { + loop_num++; + rc = fapiDelay(SBE_HALT_POLL_DELAY_HW, SBE_HALT_POLL_DELAY_SIM); + if (!rc.ok()) + { + FAPI_ERR("Error from fapiDelay"); + break; + } + + // retrieve status + rc = proc_sbe_utils_check_status( + i_target, + sbe_running, + halt_code, + istep_num, + substep_num); + if (!rc.ok()) + { + FAPI_ERR("Error from proc_check_sbe_state_check_status"); + break; + } + } + if (rc) + { + break; + } + if (sbe_running) + { + FAPI_ERR("SBE is STILL running!"); + const fapi::Target & TARGET = i_target; + FAPI_SET_HWP_ERROR(rc, RC_PROC_STOP_SBE_SCAN_SERVICE_SBE_NOT_STOPPED); + break; + } + + // before analysis proceeds, make sure that I2C master bus fence is cleared + FAPI_EXEC_HWP(rc, proc_reset_i2cm_bus_fence, i_target); + if (!rc.ok()) + { + FAPI_ERR("Error from proc_reset_i2cm_bus_fence"); + break; + } + // mark that fence has been cleared + i2cm_bus_fence_cleared = true; + + // ensure correct halt code is captured + rc = proc_sbe_utils_check_status( + i_target, + sbe_running, + halt_code, + istep_num, + substep_num); + if (!rc.ok()) + { + FAPI_ERR("Error from proc_check_sbe_state_check_status"); + break; + } + + // confirm that expected halt point was reached + if (halt_code != SBE_EXIT_SUCCESS_0xF) + { + FAPI_ERR("SBE halted with error 0x%X (istep 0x%03X, substep 0x%X)", + halt_code, istep_num, substep_num); + // extract & return error code from analyzing SBE state + FAPI_EXEC_HWP(rc, proc_extract_sbe_rc, i_target, NULL, i_pSEEPROM, SBE); + break; + } + + if ((istep_num != PROC_SBE_SCAN_SERVICE_ISTEP_NUM) || + (substep_num != SUBSTEP_HALT_SUCCESS)) + { + FAPI_ERR("Expected SBE istep 0x%03llX, substep 0x%X but found istep 0x%03X, substep 0x%X", + PROC_SBE_SCAN_SERVICE_ISTEP_NUM, SUBSTEP_HALT_SUCCESS, + istep_num, substep_num); + const fapi::Target & TARGET = i_target; + const uint32_t & ISTEP_NUM = istep_num; + const uint32_t & SUBSTEP_NUM = substep_num; + FAPI_SET_HWP_ERROR(rc, RC_PROC_STOP_SBE_SCAN_SERVICE_SBE_BAD_HALT); + break; + } + + // Reset the SBE so it can be used for MPIPL if needed + ecmdDataBufferBase sbe_reset_data(64); + rc = fapiPutScom(i_target, PORE_SBE_RESET_0x000E0002, sbe_reset_data); + if (!rc.ok()) + { + FAPI_ERR("Scom error resetting SBE\n"); + break; + } + } + // error + else + { + FAPI_ERR("SBE did not reach acceptable final state!"); + const fapi::Target & TARGET = i_target; + const bool & SBE_RUNNING = sbe_running; + const uint8_t & HALT_CODE = halt_code; + const uint16_t & ISTEP_NUM = istep_num; + const uint8_t & SUBSTEP_NUM = substep_num; + FAPI_SET_HWP_ERROR(rc, RC_PROC_STOP_SBE_SCAN_SERVICE_UNEXPECTED_FINAL_STATE); + break; + } + + } while(0); + + // if an error occurred prior to the I2C master bus fence + // being cleared, attempt to clear it prior to exit + if (!rc.ok() && !i2cm_bus_fence_cleared) + { + // discard rc, return that of original fail + fapi::ReturnCode rc_unused; + FAPI_EXEC_HWP(rc_unused, proc_reset_i2cm_bus_fence, i_target); + } + + // mark function entry + FAPI_DBG("End"); + return rc; +} + + +} // extern "C" diff --git a/src/usr/hwpf/hwp/secure_boot/proc_stop_sbe_scan_service.H b/src/usr/hwpf/hwp/secure_boot/proc_stop_sbe_scan_service.H new file mode 100644 index 000000000..4ee6d97f6 --- /dev/null +++ b/src/usr/hwpf/hwp/secure_boot/proc_stop_sbe_scan_service.H @@ -0,0 +1,79 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/secure_boot/proc_stop_sbe_scan_service.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: proc_stop_sbe_scan_service.H,v 1.1 2015/05/14 21:25:17 jmcgill Exp $ +// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/proc_stop_sbe_scan_service.H,v $ +//------------------------------------------------------------------------------ +// *| +// *! (C) Copyright International Business Machines Corp. 2015 +// *! All Rights Reserved -- Property of IBM +// *! *** *** +// *| +// *! TITLE : proc_stop_sbe_scan_service.H +// *! DESCRIPTION : Stop SBE runtime scan service +// *! +// *! OWNER NAME : Joe McGill Email: jmcgill@us.ibm.com +// *! +//------------------------------------------------------------------------------ + +#ifndef _PROC_STOP_SBE_SCAN_SERVICE_H_ +#define _PROC_STOP_SBE_SCAN_SERVICE_H_ + +//------------------------------------------------------------------------------ +// Includes +//------------------------------------------------------------------------------ +#include <fapi.H> + + +//------------------------------------------------------------------------------ +// Function prototypes +//------------------------------------------------------------------------------ + +// function pointer typedef definition for HWP call support +typedef fapi::ReturnCode (*proc_stop_sbe_scan_service_FP_t)(const fapi::Target &, + const void *); + + +//------------------------------------------------------------------------------ +// Function prototypes +//------------------------------------------------------------------------------ + +extern "C" +{ + +//------------------------------------------------------------------------------ +// function: +// Stop SBE runtime scan service +// +// parameters: i_target => chip target +// returns: FAPI_RC_SUCCESS if operation was successful, else error +//------------------------------------------------------------------------------ +fapi::ReturnCode proc_stop_sbe_scan_service( + const fapi::Target& i_target, + const void *); + + +} // extern "C" + +#endif // _PROC_STOP_SBE_SCAN_SERVICE_H_ diff --git a/src/usr/hwpf/hwp/secure_boot/proc_stop_sbe_scan_service_errors.xml b/src/usr/hwpf/hwp/secure_boot/proc_stop_sbe_scan_service_errors.xml new file mode 100644 index 000000000..233d55424 --- /dev/null +++ b/src/usr/hwpf/hwp/secure_boot/proc_stop_sbe_scan_service_errors.xml @@ -0,0 +1,87 @@ +<!-- IBM_PROLOG_BEGIN_TAG --> +<!-- This is an automatically generated prolog. --> +<!-- --> +<!-- $Source: src/usr/hwpf/hwp/secure_boot/proc_stop_sbe_scan_service_errors.xml $ --> +<!-- --> +<!-- OpenPOWER HostBoot Project --> +<!-- --> +<!-- Contributors Listed Below - COPYRIGHT 2015 --> +<!-- [+] International Business Machines Corp. --> +<!-- --> +<!-- --> +<!-- Licensed under the Apache License, Version 2.0 (the "License"); --> +<!-- you may not use this file except in compliance with the License. --> +<!-- You may obtain a copy of the License at --> +<!-- --> +<!-- http://www.apache.org/licenses/LICENSE-2.0 --> +<!-- --> +<!-- Unless required by applicable law or agreed to in writing, software --> +<!-- distributed under the License is distributed on an "AS IS" BASIS, --> +<!-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or --> +<!-- implied. See the License for the specific language governing --> +<!-- permissions and limitations under the License. --> +<!-- --> +<!-- IBM_PROLOG_END_TAG --> +<!-- $Id: proc_stop_sbe_scan_service_errors.xml,v 1.2 2015/07/27 00:49:30 jmcgill Exp $ --> +<!-- Error definitions for proc_stop_sbe_scan_service procedure --> +<hwpErrors> + <!-- *********************************************************************** --> + <hwpError> + <rc>RC_PROC_STOP_SBE_SCAN_SERVICE_SBE_NOT_STOPPED</rc> + <description> + Procedure: proc_stop_sbe_scan_service + The slave SBE is still running, when expected to be halted + </description> + <ffdc>TARGET</ffdc> + <collectRegisterFfdc> + <id>REG_FFDC_PROC_STATUS_AND_SBE_VITAL_REGISTERS</id> + <id>REG_FFDC_PROC_SBE_REGISTERS</id> + <target>TARGET</target> + </collectRegisterFfdc> + <callout> + <target>TARGET</target> + <priority>LOW</priority> + </callout> + </hwpError> + <!-- *********************************************************************** --> + <hwpError> + <rc>RC_PROC_STOP_SBE_SCAN_SERVICE_SBE_BAD_HALT</rc> + <description> + Procedure: proc_stop_sbe_scan_service + The slave SBE is not halted at the correct istep/substep number + </description> + <ffdc>TARGET</ffdc> + <ffdc>ISTEP_NUM</ffdc> + <ffdc>SUBSTEP_NUM</ffdc> + <collectRegisterFfdc> + <id>REG_FFDC_PROC_STATUS_AND_SBE_VITAL_REGISTERS</id> + <id>REG_FFDC_PROC_SBE_REGISTERS</id> + <target>TARGET</target> + </collectRegisterFfdc> + <deconfigure> + <target>TARGET</target> + </deconfigure> + </hwpError> + <!-- *********************************************************************** --> + <hwpError> + <rc>RC_PROC_STOP_SBE_SCAN_SERVICE_UNEXPECTED_FINAL_STATE</rc> + <description> + Procedure: proc_stop_sbe_scan_service + SBE did not reahch acceptable final state + </description> + <ffdc>TARGET</ffdc> + <ffdc>SBE_RUNNING</ffdc> + <ffdc>HALT_CODE</ffdc> + <ffdc>ISTEP_NUM</ffdc> + <ffdc>SUBSTEP_NUM</ffdc> + <collectRegisterFfdc> + <id>REG_FFDC_PROC_STATUS_AND_SBE_VITAL_REGISTERS</id> + <id>REG_FFDC_PROC_SBE_REGISTERS</id> + <target>TARGET</target> + </collectRegisterFfdc> + <deconfigure> + <target>TARGET</target> + </deconfigure> + </hwpError> + <!-- *********************************************************************** --> +</hwpErrors> diff --git a/src/usr/hwpf/hwp/secure_boot/proc_use_sbe_scan_service.C b/src/usr/hwpf/hwp/secure_boot/proc_use_sbe_scan_service.C new file mode 100644 index 000000000..b24bc416e --- /dev/null +++ b/src/usr/hwpf/hwp/secure_boot/proc_use_sbe_scan_service.C @@ -0,0 +1,148 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/secure_boot/proc_use_sbe_scan_service.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: proc_use_sbe_scan_service.C,v 1.1 2015/05/14 21:49:17 jmcgill Exp $ +// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/proc_use_sbe_scan_service.C,v $ +//------------------------------------------------------------------------------ +// *| +// *! (C) Copyright International Business Machines Corp. 2015 +// *! All Rights Reserved -- Property of IBM +// *! *** *** +// *| +// *! TITLE : proc_use_sbe_scan_service.C +// *! DESCRIPTION : Shared routine used to determine use of SBE runtime scan +// *! service +// *! +// *! OWNER NAME : Joe McGill Email: jmcgill@us.ibm.com +// *! +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ +// Includes +//------------------------------------------------------------------------------ +#include <p8_scom_addresses.H> +#include <proc_use_sbe_scan_service.H> +#include <proc_check_master_sbe_seeprom.H> +#include <proc_check_security.H> + +//------------------------------------------------------------------------------ +// Constant definitions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// Function definitions +//------------------------------------------------------------------------------ + +extern "C" +{ + +//------------------------------------------------------------------------------ +// function: +// Use SBE runtime scan service? +// +// parameters: i_target => chip target +// returns: FAPI_RC_SUCCESS if operation was successful, else error +//------------------------------------------------------------------------------ +fapi::ReturnCode proc_use_sbe_scan_service( + const fapi::Target& i_target, + bool& o_use_sbe_scan_service) +{ + // return codes + fapi::ReturnCode rc; + + // mark function entry + FAPI_DBG("Start"); + + do + { + // make determination of scan path to use + // use SBE scan service if: + // processor chip target AND + // slave chip AND + // ((secure boot enabled OR ATTR_FORCE_USE_SBE_SLAVE_SCAN_SERVICE) AND !ATTR_TRUSTED_SLAVE_SCAN_PATH_ACTIVE) + + // check for processor chip target + o_use_sbe_scan_service = (i_target.getType() == fapi::TARGET_TYPE_PROC_CHIP); + // check for slave chip + if (o_use_sbe_scan_service) + { + bool is_master; + FAPI_EXEC_HWP(rc, proc_check_master_sbe_seeprom, i_target, is_master); + if (!rc.ok()) + { + FAPI_ERR("Error from proc_check_master_sbe_seeprom"); + break; + } + o_use_sbe_scan_service = !is_master; + } + // check for security state/attribute direction + if (o_use_sbe_scan_service) + { + bool is_secure; + FAPI_EXEC_HWP(rc, proc_check_security, i_target, is_secure); + if (!rc.ok()) + { + FAPI_ERR("Error from proc_check_security"); + break; + } + o_use_sbe_scan_service = is_secure; + + // force use of SBE scan service by attribute + if (!o_use_sbe_scan_service) + { + fapi::ATTR_FORCE_USE_SBE_SLAVE_SCAN_SERVICE_Type force_use_sbe_attr; + rc = FAPI_ATTR_GET(ATTR_FORCE_USE_SBE_SLAVE_SCAN_SERVICE, NULL, force_use_sbe_attr); + if (!rc.ok()) + { + FAPI_ERR("Error reading ATTR_FORCE_USE_SBE_SLAVE_SCAN_SERVICE"); + break; + } + + o_use_sbe_scan_service = (force_use_sbe_attr == fapi::ENUM_ATTR_FORCE_USE_SBE_SLAVE_SCAN_SERVICE_TRUE); + } + + // discontinue use of SBE scan service once trusted scan path is available + if (o_use_sbe_scan_service) + { + fapi::ATTR_TRUSTED_SLAVE_SCAN_PATH_ACTIVE_Type trusted_slave_scan_path_active; + rc = FAPI_ATTR_GET(ATTR_TRUSTED_SLAVE_SCAN_PATH_ACTIVE, NULL, trusted_slave_scan_path_active); + if (!rc.ok()) + { + FAPI_ERR("Error reading ATTR_TRUSTED_SLAVE_SCAN_PATH_ACTIVE"); + break; + } + + o_use_sbe_scan_service = (trusted_slave_scan_path_active == fapi::ENUM_ATTR_TRUSTED_SLAVE_SCAN_PATH_ACTIVE_FALSE); + } + } + } while(0); + + // mark function entry + FAPI_DBG("End"); + return rc; +} + + +} // extern "C" diff --git a/src/usr/hwpf/hwp/secure_boot/proc_use_sbe_scan_service.H b/src/usr/hwpf/hwp/secure_boot/proc_use_sbe_scan_service.H new file mode 100644 index 000000000..69532ee63 --- /dev/null +++ b/src/usr/hwpf/hwp/secure_boot/proc_use_sbe_scan_service.H @@ -0,0 +1,80 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/secure_boot/proc_use_sbe_scan_service.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: proc_use_sbe_scan_service.H,v 1.1 2015/05/14 21:49:21 jmcgill Exp $ +// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/proc_use_sbe_scan_service.H,v $ +//------------------------------------------------------------------------------ +// *| +// *! (C) Copyright International Business Machines Corp. 2015 +// *! All Rights Reserved -- Property of IBM +// *! *** *** +// *| +// *! TITLE : proc_use_sbe_scan_service.H +// *! DESCRIPTION : Shared routine used to determine use of SBE runtime scan +// *! service +// *! +// *! OWNER NAME : Joe McGill Email: jmcgill@us.ibm.com +// *! +//------------------------------------------------------------------------------ + +#ifndef _PROC_USE_SBE_SCAN_SERVICE_H_ +#define _PROC_USE_SBE_SCAN_SERVICE_H_ + +//------------------------------------------------------------------------------ +// Includes +//------------------------------------------------------------------------------ +#include <fapi.H> + + +//------------------------------------------------------------------------------ +// Function prototypes +//------------------------------------------------------------------------------ + +// function pointer typedef definition for HWP call support +typedef fapi::ReturnCode (*proc_use_sbe_scan_service_FP_t)(const fapi::Target &, + bool &); + + +//------------------------------------------------------------------------------ +// Function prototypes +//------------------------------------------------------------------------------ + +extern "C" +{ + +//------------------------------------------------------------------------------ +// function: +// Use SBE runtime scan service? +// +// parameters: i_target => chip target +// returns: FAPI_RC_SUCCESS if operation was successful, else error +//------------------------------------------------------------------------------ +fapi::ReturnCode proc_use_sbe_scan_service( + const fapi::Target& i_target, + bool& o_use_sbe_scan_service); + + +} // extern "C" + +#endif // _PROC_USE_SBE_SCAN_SERVICE_H_ diff --git a/src/usr/hwpf/hwp/slave_sbe/makefile b/src/usr/hwpf/hwp/slave_sbe/makefile index a29cb24ae..93a08aef3 100644 --- a/src/usr/hwpf/hwp/slave_sbe/makefile +++ b/src/usr/hwpf/hwp/slave_sbe/makefile @@ -5,7 +5,7 @@ # # OpenPOWER HostBoot Project # -# Contributors Listed Below - COPYRIGHT 2012,2014 +# Contributors Listed Below - COPYRIGHT 2012,2015 # [+] International Business Machines Corp. # # @@ -48,6 +48,8 @@ EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/slave_sbe/proc_tp_collect_dbg_data EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/pstates/pstates EXTRAINCDIR += ${ROOTPATH}/src/usr/pore/poreve/porevesrc EXTRAINCDIR += ${ROOTPATH}/src/usr/pore/poreve/model/ +EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/secure_boot +EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/core_activate/proc_stop_deadman_timer ## NOTE: add new object files when you add a new HWP OBJS += slave_sbe.o diff --git a/src/usr/hwpf/hwp/slave_sbe/proc_check_slave_sbe_seeprom_complete/proc_check_slave_sbe_seeprom_complete.C b/src/usr/hwpf/hwp/slave_sbe/proc_check_slave_sbe_seeprom_complete/proc_check_slave_sbe_seeprom_complete.C index 93fa44dd6..7f13acc5c 100644 --- a/src/usr/hwpf/hwp/slave_sbe/proc_check_slave_sbe_seeprom_complete/proc_check_slave_sbe_seeprom_complete.C +++ b/src/usr/hwpf/hwp/slave_sbe/proc_check_slave_sbe_seeprom_complete/proc_check_slave_sbe_seeprom_complete.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2012,2014 */ +/* Contributors Listed Below - COPYRIGHT 2012,2015 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -23,7 +23,7 @@ /* */ /* IBM_PROLOG_END_TAG */ // -*- mode: C++; c-file-style: "linux"; -*- -// $Id: proc_check_slave_sbe_seeprom_complete.C,v 1.16 2014/08/05 15:16:19 kahnevan Exp $ +// $Id: proc_check_slave_sbe_seeprom_complete.C,v 1.18 2015/07/27 00:36:23 jmcgill Exp $ // $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/proc_check_slave_sbe_seeprom_complete.C,v $ //------------------------------------------------------------------------------ // *| @@ -36,9 +36,6 @@ // *! // *! OWNER NAME : Joe McGill Email: jmcgill@us.ibm.com // *! -// *! Overview: -// *! Check if the SBE is still running -// *! Check if the SBE stopped with success at the correct spot //------------------------------------------------------------------------------ @@ -50,257 +47,128 @@ #include <p8_istep_num.H> #include <proc_sbe_check_master.H> #include <proc_sbe_enable_pnor.H> +#include <proc_sbe_scan_service.H> #include <proc_extract_sbe_rc.H> #include <proc_reset_i2cm_bus_fence.H> +#include <proc_sbe_utils.H> + //------------------------------------------------------------------------------ // Constant definitions //------------------------------------------------------------------------------ -const uint8_t SBE_STOPPED_AT_BREAKPOINT_0xB = 0xB; -const uint8_t SBE_EXIT_SUCCESS_0xF = 0xF; const uint64_t NS_TO_FINISH = 10000000; //(10 ms) const uint64_t MS_TO_FINISH = NS_TO_FINISH/1000000; const uint64_t SIM_CYCLES_TO_FINISH = 10000000; -//Should really be 19.6*NS_TO_FINISH, but sim runs at about 11 hours per -//simulated second which is longer than we want to wait in error cases - - -extern "C" -{ - -//------------------------------------------------------------------------------ -// Subroutine definitions -//------------------------------------------------------------------------------ -//------------------------------------------------------------------------------ -// subroutine: -// Get the SBE location from SBE VITAL -// -// parameters: i_target => slave chip target -// o_halt_code => halt code (only valid if SBE stopped) -// o_istep_num => current istep number (0xMmm) -// o_substep_num => current substep within istep -// -// returns: FAPI_RC_SUCCESS if o_istep_num and o_substep_num are valid, -// else error -//------------------------------------------------------------------------------ - fapi::ReturnCode proc_check_slave_sbe_seeprom_complete_get_location( - const fapi::Target & i_target, - uint8_t & o_halt_code, - uint16_t & o_istep_num, - uint8_t & o_substep_num - ) - { - // data buffer to hold register values - ecmdDataBufferBase data(64); - - // return codes - uint32_t rc_ecmd = 0; - fapi::ReturnCode rc; - do - { - //Check SBE VITAL - FAPI_DBG("Checking SBE VITAL reg"); - rc = fapiGetScom(i_target, MBOX_SBEVITAL_0x0005001C, data); - if(rc) - { - FAPI_ERR("Error reading SBE VITAL reg\n"); - break; - } - - o_halt_code = 0; - o_istep_num = 0; - o_substep_num = 0; - rc_ecmd |= data.extractToRight(&o_halt_code, - HALT_CODE_BIT_POSITION, - HALT_CODE_BIT_LENGTH); - rc_ecmd |= data.extractToRight(&o_istep_num, - ISTEP_NUM_BIT_POSITION, - ISTEP_NUM_BIT_LENGTH); - rc_ecmd |= data.extractToRight(&o_substep_num, - SUBSTEP_NUM_BIT_POSITION, - SUBSTEP_NUM_BIT_LENGTH); - if(rc_ecmd) - { - FAPI_ERR("Error (0x%x) extracting data from ecmdDataBufferBase", - rc_ecmd); - rc.setEcmdError(rc_ecmd); - break; - } - } while(0); - return rc; - } +const uint8_t SBE_EXIT_SUCCESS_0xF = 0xF; //------------------------------------------------------------------------------ -// subroutine: -// Check if the SBE is still running -// -// parameters: i_target => slave chip target -// o_still_running => true if still running, false otherwise -// -// returns: FAPI_RC_SUCCESS if o_still_running is valid, else error +// Function definitions //------------------------------------------------------------------------------ - fapi::ReturnCode proc_check_slave_sbe_seeprom_complete_check_running( - const fapi::Target & i_target, - bool & o_still_running ) - { - // data buffer to hold register values - ecmdDataBufferBase data(64); - - // return codes - uint32_t rc_ecmd = 0; - fapi::ReturnCode rc; - do - { - FAPI_DBG("Checking SBE control reg"); - rc = fapiGetScom(i_target, PORE_SBE_CONTROL_0x000E0001, data); - if(rc) - { - FAPI_ERR("Error reading SBE control reg\n"); - break; - } - - // Bit 0 : 1 = stopped, 0 = running (or stopped at breakpoint) - if( data.isBitClear(0) ) - { - o_still_running = true; +extern "C" +{ - //If running, check for stopped at breakpoint - FAPI_DBG("Checking SBE status reg"); - rc = fapiGetScom(i_target, PORE_SBE_STATUS_0x000E0000, data); - if(rc) - { - FAPI_ERR("Error reading SBE status reg\n"); - break; - } - uint8_t state = 0; - uint64_t address = data.getDoubleWord(0) & - 0x0000FFFFFFFFFFFFull; - rc_ecmd |= data.extractToRight( &state, 3, 4 ); - if(rc_ecmd) - { - FAPI_ERR("Error (0x%x) extracting SBE status", - rc_ecmd); - rc.setEcmdError(rc_ecmd); - break; - } +fapi::ReturnCode proc_check_slave_sbe_seeprom_complete( + const fapi::Target & i_target, + const void * i_pSEEPROM, + const size_t i_wait_in_ms) +{ + // return codes + fapi::ReturnCode rc; - if( state == SBE_STOPPED_AT_BREAKPOINT_0xB ) - { - FAPI_ERR("SBE stopped at breakpoint (address 0x%012llX)", - address); - const fapi::Target & CHIP_IN_ERROR = i_target; - FAPI_SET_HWP_ERROR(rc, - RC_PROC_CHECK_SLAVE_SBE_SEEPROM_COMPLETE_STOPPED_AT_BREAKPOINT); - break; - } - } - else - { - o_still_running = false; - } - } while(0); - return rc; - } + // track if procedure has cleared I2C master bus fence + bool i2cm_bus_fence_cleared = false; -//------------------------------------------------------------------------------ -// Function definitions -//------------------------------------------------------------------------------ + // mark function entry + FAPI_INF("Start"); -//------------------------------------------------------------------------------ -// function: -// Check if the SBE is still running -// Wait 1 sec, then check again if still running -// When stopped, check if the SBE halt code, istep, and substep are correct -// -// parameters: i_target => slave chip target -// i_pSEEPROM => pointer to the seeprom image (for errors) -// i_wait_in_ms => pointer to the seeprom image (for errors) -// -// returns: FAPI_RC_SUCCESS if the slave SBE stopped with success at the correct -// location, else error -//------------------------------------------------------------------------------ - fapi::ReturnCode proc_check_slave_sbe_seeprom_complete( - const fapi::Target & i_target, - const void * i_pSEEPROM, - const size_t i_wait_in_ms) + do { - // data buffer to hold register values - ecmdDataBufferBase data(64); - - // return codes - uint32_t rc_ecmd = 0; - fapi::ReturnCode rc; - - // track if procedure has cleared I2C master bus fence - bool i2cm_bus_fence_cleared = false; - - // mark function entry - FAPI_INF("Entry"); + // + // ensure SBE was started + // + + ecmdDataBufferBase sbe_vital_data(32); + FAPI_DBG("Checking SBE Vital register"); + rc = fapiGetCfamRegister(i_target, CFAM_FSI_SBE_VITAL_0x0000281C, sbe_vital_data); + if (!rc.ok()) + { + FAPI_ERR("Error reading SBE Vital register"); + break; + } + if (sbe_vital_data.isBitClear(12,20)) + { + // status has not been updated, something is wrong + FAPI_ERR("SBE does not appear to have started"); + // Call proc_extract_sbe_rc here to see what went wrong + FAPI_EXEC_HWP(rc, proc_extract_sbe_rc, i_target, NULL, i_pSEEPROM, SBE); + break; + } - do + // + // check SBE progress + // Loop until: + // SBE stopped OR + // scan service ready loop is reached OR + // loop time is exceeded + // + + bool sbe_running = true; + size_t loop_time = 0; + uint8_t halt_code = 0; + uint16_t istep_num = 0; + uint8_t substep_num = 0; + bool scan_service_loop_reached = false; + while (sbe_running && + !scan_service_loop_reached && + (loop_time < i_wait_in_ms)) { - //Check if the SBE is still running. Loop until stopped - //or loop time is exceeded. - bool still_running = true; - size_t loop_time = 0; - rc = proc_check_slave_sbe_seeprom_complete_check_running( - i_target, - still_running ); - if( rc ) + // sleep 10ms, then check again + loop_time += MS_TO_FINISH; + rc = fapiDelay(NS_TO_FINISH, SIM_CYCLES_TO_FINISH); + if (rc) { + FAPI_ERR("Error from fapiDelay"); break; } - while (still_running && (loop_time < i_wait_in_ms)) - { - //Not done -- sleep 10ms, then check again - loop_time += MS_TO_FINISH; - rc = fapiDelay(NS_TO_FINISH, SIM_CYCLES_TO_FINISH); - if( rc ) - { - FAPI_ERR("Error with delay\n"); - break; - } - - rc = proc_check_slave_sbe_seeprom_complete_check_running( - i_target, - still_running ); - if( rc ) - { - break; - } - } - - //Break if took an error - if( rc ) + // retrieve status + rc = proc_sbe_utils_check_status( + i_target, + sbe_running, + halt_code, + istep_num, + substep_num); + if (!rc.ok()) { + FAPI_ERR("Error from proc_check_sbe_state_check_status"); break; } - FAPI_INF("SBE is running [%d], wait time in ms[%zd]", - still_running, loop_time); + scan_service_loop_reached = + sbe_running && + !halt_code && + (istep_num == PROC_SBE_SCAN_SERVICE_ISTEP_NUM) && + (substep_num == SUBSTEP_SBE_READY); + } - //Give up if we're still running - if( still_running ) - { - FAPI_ERR( - "SBE still running after waiting (%zdns, %lld cycles)", - loop_time, - loop_time/MS_TO_FINISH*SIM_CYCLES_TO_FINISH ); + // break if we took an error in the while loop + if (rc) + { + break; + } - const fapi::Target & CHIP_IN_ERROR = i_target; - FAPI_SET_HWP_ERROR(rc, - RC_PROC_CHECK_SLAVE_SBE_SEEPROM_COMPLETE_STILL_RUNNING); - break; - } //end if(still_running) + FAPI_INF("SBE is running [%d], loop time [%zd], scan service loop reached [%d]", + sbe_running, loop_time, scan_service_loop_reached); - //SBE is stopped. Let's see where - uint8_t halt_code = 0; - uint16_t istep_num = 0; - uint8_t substep_num = 0; + // two valid possibilities + // 1) SBE halted with success + // 2) scan service routine is running + if (!sbe_running) + { + //SBE is stopped. Let's see where // before analysis proceeds, make sure that I2C master bus fence is cleared FAPI_EXEC_HWP(rc, proc_reset_i2cm_bus_fence, i_target); if (!rc.ok()) @@ -311,104 +179,76 @@ extern "C" // mark that fence has been cleared i2cm_bus_fence_cleared = true; - //Get current location from SBE VITAL - rc = proc_check_slave_sbe_seeprom_complete_get_location( - i_target, - halt_code, - istep_num, - substep_num ); - if( rc ) + // did it stop with success? + if (halt_code != SBE_EXIT_SUCCESS_0xF) { - FAPI_ERR("Unable to get the current SBE location"); - break; - } - - //Did it stop with success? - if( halt_code != SBE_EXIT_SUCCESS_0xF ) - { - FAPI_ERR( - "SBE halted with error %i (istep 0x%X, substep %i)", - halt_code, - istep_num, - substep_num); - //Get the error code from the SBE code + FAPI_ERR("SBE halted with error %i (istep 0x%X, substep %i)", + halt_code, + istep_num, + substep_num); FAPI_EXEC_HWP(rc, proc_extract_sbe_rc, i_target, NULL, i_pSEEPROM, SBE); break; } - //Halt code was success - //Did it stop in the correct istep? - if(( istep_num != PROC_SBE_CHECK_MASTER_MAGIC_ISTEP_NUM ) && - ( istep_num != PROC_SBE_ENABLE_PNOR_MAGIC_ISTEP_NUM ) && - ( istep_num != PROC_SBE_EX_HOST_RUNTIME_SCOM_MAGIC_ISTEP_NUM )) + // did it stop in the correct istep? + if (!(((istep_num == PROC_SBE_CHECK_MASTER_MAGIC_ISTEP_NUM ) && + (substep_num == SUBSTEP_CHECK_MASTER_SLAVE_CHIP)) || + ((istep_num == PROC_SBE_ENABLE_PNOR_MAGIC_ISTEP_NUM ) && + (substep_num == SUBSTEP_ENABLE_PNOR_SLAVE_CHIP)) || + (istep_num == PROC_SBE_EX_HOST_RUNTIME_SCOM_MAGIC_ISTEP_NUM))) { FAPI_ERR( - "SBE halted in wrong istep (istep 0x%X, substep %i)", + "SBE halted in wrong istep (istep 0x%X, substep %i)", istep_num, substep_num); const fapi::Target & CHIP_IN_ERROR = i_target; uint16_t & ISTEP_NUM = istep_num; uint8_t & SUBSTEP_NUM = substep_num; - FAPI_SET_HWP_ERROR(rc, - RC_PROC_CHECK_SLAVE_SBE_SEEPROM_COMPLETE_BAD_ISTEP_NUM); + FAPI_SET_HWP_ERROR(rc, RC_PROC_CHECK_SLAVE_SBE_SEEPROM_COMPLETE_BAD_ISTEP_NUM); break; } - //Istep is correct - - //Did it stop in the correct substep? - if( (( istep_num == PROC_SBE_CHECK_MASTER_MAGIC_ISTEP_NUM ) && - ( substep_num != SUBSTEP_CHECK_MASTER_SLAVE_CHIP )) || - (( istep_num == PROC_SBE_ENABLE_PNOR_MAGIC_ISTEP_NUM ) && - ( substep_num != SUBSTEP_ENABLE_PNOR_SLAVE_CHIP ))) - { - FAPI_ERR( - "SBE halted in wrong substep (istep 0x%X, substep %i)", - istep_num, - substep_num); - const fapi::Target & CHIP_IN_ERROR = i_target; - uint16_t & ISTEP_NUM = istep_num; - uint8_t & SUBSTEP_NUM = substep_num; - FAPI_SET_HWP_ERROR(rc, - RC_PROC_CHECK_SLAVE_SBE_SEEPROM_COMPLETE_BAD_SUBSTEP_NUM); - break; - } - //Substep is correct - - //Looks good! - - // Reset the SBE so it can be used for MPIPL if needed - rc_ecmd |= data.flushTo0(); - rc_ecmd |= data.setBit(0); - if(rc_ecmd) - { - FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", rc_ecmd); - rc.setEcmdError(rc_ecmd); - break; - } - rc = fapiPutScom(i_target, PORE_SBE_RESET_0x000E0002, data); - if(!rc.ok()) + // reset the SBE so it can be used for MPIPL if needed + rc = proc_sbe_utils_reset_sbe(i_target); + if (!rc.ok()) { - FAPI_ERR("Scom error resetting SBE\n"); + FAPI_ERR("Error from proc_sbe_utils_reset_sbe"); break; } - } while (0); - - // if an error occurred prior to the I2C master bus fence - // being cleared, attempt to clear it prior to exit - if (!rc.ok() && !i2cm_bus_fence_cleared) + } + else if (scan_service_loop_reached) { - // discard rc, return that of original fail - fapi::ReturnCode rc_unused; - FAPI_EXEC_HWP(rc_unused, proc_reset_i2cm_bus_fence, i_target); + FAPI_INF("SBE finished, scan service is running!"); + break; } + // error + else + { + FAPI_ERR("SBE did not reach acceptable final state!"); + const fapi::Target & CHIP_IN_ERROR = i_target; + const bool & SBE_RUNNING = sbe_running; + const uint8_t & HALT_CODE = halt_code; + const uint16_t & ISTEP_NUM = istep_num; + const uint8_t & SUBSTEP_NUM = substep_num; + FAPI_SET_HWP_ERROR(rc, RC_PROC_CHECK_SLAVE_SBE_SEEPROM_COMPLETE_UNEXPECTED_FINAL_STATE); + break; + } + + } while (0); - // mark function exit - FAPI_INF("Exit"); - return rc; + // if an error occurred prior to the I2C master bus fence + // being cleared, attempt to clear it prior to exit + if (!rc.ok() && !i2cm_bus_fence_cleared) + { + // discard rc, return that of original fail + fapi::ReturnCode rc_unused; + FAPI_EXEC_HWP(rc_unused, proc_reset_i2cm_bus_fence, i_target); } + // mark function exit + FAPI_INF("Exit"); + return rc; +} + + } // extern "C" -/* Local Variables: */ -/* c-basic-offset: 4 */ -/* End: */ diff --git a/src/usr/hwpf/hwp/slave_sbe/proc_check_slave_sbe_seeprom_complete/proc_check_slave_sbe_seeprom_complete_errors.xml b/src/usr/hwpf/hwp/slave_sbe/proc_check_slave_sbe_seeprom_complete/proc_check_slave_sbe_seeprom_complete_errors.xml index 60839e2f1..ee658c384 100644 --- a/src/usr/hwpf/hwp/slave_sbe/proc_check_slave_sbe_seeprom_complete/proc_check_slave_sbe_seeprom_complete_errors.xml +++ b/src/usr/hwpf/hwp/slave_sbe/proc_check_slave_sbe_seeprom_complete/proc_check_slave_sbe_seeprom_complete_errors.xml @@ -5,7 +5,9 @@ <!-- --> <!-- OpenPOWER HostBoot Project --> <!-- --> -<!-- COPYRIGHT International Business Machines Corp. 2012,2014 --> +<!-- Contributors Listed Below - COPYRIGHT 2012,2015 --> +<!-- [+] International Business Machines Corp. --> +<!-- --> <!-- --> <!-- Licensed under the Apache License, Version 2.0 (the "License"); --> <!-- you may not use this file except in compliance with the License. --> @@ -20,44 +22,11 @@ <!-- permissions and limitations under the License. --> <!-- --> <!-- IBM_PROLOG_END_TAG --> -<!-- $Id: proc_check_slave_sbe_seeprom_complete_errors.xml,v 1.6 2014/02/10 02:22:27 stillgs Exp $ --> +<!-- $Id: proc_check_slave_sbe_seeprom_complete_errors.xml,v 1.8 2015/07/27 00:37:13 jmcgill Exp $ --> <!-- Error definitions for proc_check_slave_sbe_seeprom_complete procedure --> <hwpErrors> <!-- *********************************************************************** --> <hwpError> - <rc>RC_PROC_CHECK_SLAVE_SBE_SEEPROM_COMPLETE_STOPPED_AT_BREAKPOINT</rc> - <description> - Procedure: proc_check_slave_sbe_seeprom_complete - The slave SBE is stopped at a breakpoint - </description> - <collectRegisterFfdc> - <id>REG_FFDC_PROC_STATUS_AND_SBE_VITAL_REGISTERS</id> - <id>REG_FFDC_PROC_SBE_REGISTERS</id> - <target>CHIP_IN_ERROR</target> - </collectRegisterFfdc> - <callout> - <target>CHIP_IN_ERROR</target> - <priority>LOW</priority> - </callout> - </hwpError> - <!-- *********************************************************************** --> - <hwpError> - <rc>RC_PROC_CHECK_SLAVE_SBE_SEEPROM_COMPLETE_STILL_RUNNING</rc> - <description> - Procedure: proc_check_slave_sbe_seeprom_complete - The slave SBE is still running - </description> - <collectRegisterFfdc> - <id>REG_FFDC_PROC_STATUS_AND_SBE_VITAL_REGISTERS</id> - <id>REG_FFDC_PROC_SBE_REGISTERS</id> - <target>CHIP_IN_ERROR</target> - </collectRegisterFfdc> - <deconfigure> - <target>CHIP_IN_ERROR</target> - </deconfigure> - </hwpError> - <!-- *********************************************************************** --> - <hwpError> <rc>RC_PROC_CHECK_SLAVE_SBE_SEEPROM_COMPLETE_BAD_ISTEP_NUM</rc> <description> Procedure: proc_check_slave_sbe_seeprom_complete @@ -76,11 +45,13 @@ </hwpError> <!-- *********************************************************************** --> <hwpError> - <rc>RC_PROC_CHECK_SLAVE_SBE_SEEPROM_COMPLETE_BAD_SUBSTEP_NUM</rc> + <rc>RC_PROC_CHECK_SLAVE_SBE_SEEPROM_COMPLETE_UNEXPECTED_FINAL_STATE</rc> <description> Procedure: proc_check_slave_sbe_seeprom_complete - The slave SBE is not at the correct substep number + The slave SBE did not reach a valid final state </description> + <ffdc>SBE_RUNNING</ffdc> + <ffdc>HALT_CODE</ffdc> <ffdc>ISTEP_NUM</ffdc> <ffdc>SUBSTEP_NUM</ffdc> <collectRegisterFfdc> @@ -92,4 +63,5 @@ <target>CHIP_IN_ERROR</target> </deconfigure> </hwpError> + <!-- *********************************************************************** --> </hwpErrors> diff --git a/src/usr/hwpf/hwp/slave_sbe/proc_getecid/proc_getecid.C b/src/usr/hwpf/hwp/slave_sbe/proc_getecid/proc_getecid.C index 30ecbcbae..bafa8aa55 100644 --- a/src/usr/hwpf/hwp/slave_sbe/proc_getecid/proc_getecid.C +++ b/src/usr/hwpf/hwp/slave_sbe/proc_getecid/proc_getecid.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2013,2014 */ +/* Contributors Listed Below - COPYRIGHT 2013,2015 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -22,7 +22,7 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: proc_getecid.C,v 1.10 2014/10/03 21:56:44 jmcgill Exp $ +// $Id: proc_getecid.C,v 1.11 2015/05/14 21:14:31 jmcgill Exp $ // $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/utils/proc_getecid.C,v $ //------------------------------------------------------------------------------ // *| @@ -42,15 +42,12 @@ // Includes //------------------------------------------------------------------------------ #include <proc_getecid.H> - +#include <proc_check_security.H> //------------------------------------------------------------------------------ // Constant definitions //------------------------------------------------------------------------------ -// Security Switch register field/bit definitions -const uint32_t OTPC_M_SECURITY_SWITCH_TRUSTED_BOOT_BIT = 1; - // OTPROM mode register field/bit definitions const uint32_t OTPC_M_MODE_REGISTER_ECC_ENABLE_BIT = 1; @@ -88,23 +85,20 @@ fapi::ReturnCode proc_getecid( // determine if security is enabled // - rc = fapiGetScom(i_target, OTPC_M_SECURITY_SWITCH_0x00010005, security_switch_data); + FAPI_EXEC_HWP(rc, proc_check_security, i_target, secure_mode); if (!rc.ok()) { - FAPI_ERR("proc_getecid: fapiGetScom error (OTPC_M_SECURITY_SWITCH_0x00010005) for %s", - i_target.toEcmdString()); + FAPI_ERR("Error from proc_check_security"); break; } - secure_mode = security_switch_data.isBitSet(OTPC_M_SECURITY_SWITCH_TRUSTED_BOOT_BIT); - // // clear ECC enable before reading ECID data (read-modify-write OTPROM Mode register), insecure mode only // if (!secure_mode) { - + rc = fapiGetScom(i_target, OTPC_M_MODE_REGISTER_0x00010008, otprom_mode_data); if (!rc.ok()) { @@ -112,7 +106,7 @@ fapi::ReturnCode proc_getecid( i_target.toEcmdString()); break; } - + rc_ecmd |= otprom_mode_data.clearBit(OTPC_M_MODE_REGISTER_ECC_ENABLE_BIT); if (rc_ecmd) { @@ -121,7 +115,7 @@ fapi::ReturnCode proc_getecid( rc.setEcmdError(rc_ecmd); break; } - + rc = fapiPutScom(i_target, OTPC_M_MODE_REGISTER_0x00010008, otprom_mode_data); if (!rc.ok()) { @@ -134,7 +128,7 @@ fapi::ReturnCode proc_getecid( // // extract and manipulate ECID data // - + rc = fapiGetScom(i_target, ECID_PART_0_0x00018000, ecid_data); if (!rc.ok()) { @@ -142,13 +136,13 @@ fapi::ReturnCode proc_getecid( i_target.toEcmdString()); break; } - + // 0:63 become 63:0 rc_ecmd |= ecid_data.reverse(); // copy bits 0:63 from the scom into 0:63 of the fuseString/attribute data rc_ecmd |= io_fuseString.insert(ecid_data, 0, 64); attr_data[0] = ecid_data.getDoubleWord(0); - + if (rc_ecmd) { FAPI_ERR("proc_getecid: Error 0x%X processing ECID (part 0) data buffer", @@ -156,7 +150,7 @@ fapi::ReturnCode proc_getecid( rc.setEcmdError(rc_ecmd); break; } - + rc = fapiGetScom(i_target, ECID_PART_1_0x00018001, ecid_data); if (!rc.ok()) { @@ -164,14 +158,14 @@ fapi::ReturnCode proc_getecid( i_target.toEcmdString()); break; } - + // 0:63 become 63:0 rc_ecmd |= ecid_data.reverse(); // copy bits 0:47 from the scom into 64:111 of the fuseString // all bits into attribute data rc_ecmd |= io_fuseString.insert(ecid_data, 64, 48); attr_data[1] = ecid_data.getDoubleWord(0); - + if (rc_ecmd) { FAPI_ERR("proc_getecid: Error 0x%X processing ECID (part 1) data buffer", @@ -179,7 +173,7 @@ fapi::ReturnCode proc_getecid( rc.setEcmdError(rc_ecmd); break; } - + // push fuse string into attribute rc = FAPI_ATTR_SET(ATTR_ECID, &i_target, @@ -205,7 +199,7 @@ fapi::ReturnCode proc_getecid( rc.setEcmdError(rc_ecmd); break; } - + rc = fapiPutScom(i_target, OTPC_M_MODE_REGISTER_0x00010008, otprom_mode_data); if (!rc.ok()) { diff --git a/src/usr/hwpf/makefile b/src/usr/hwpf/makefile index afc091db2..895391004 100644 --- a/src/usr/hwpf/makefile +++ b/src/usr/hwpf/makefile @@ -186,6 +186,8 @@ HWP_ERROR_XML_FILES += hwp/proc_pba_utils_registers.xml HWP_ERROR_XML_FILES += hwp/p8_fir_registers.xml HWP_ERROR_XML_FILES += hwp/cen_fir_registers.xml HWP_ERROR_XML_FILES += hwp/tp_dbg_data_accessors/proc_tp_dbg_data_errors.xml +HWP_ERROR_XML_FILES += hwp/secure_boot/proc_sbe_scan_service_errors.xml +HWP_ERROR_XML_FILES += hwp/secure_boot/proc_stop_sbe_scan_service_errors.xml ## these get generated into obj/genfiles/AttributeIds.H HWP_ATTR_XML_FILES += hwp/memory_attributes.xml |