diff options
Diffstat (limited to 'sbe/sample/pk_scom.c')
-rw-r--r-- | sbe/sample/pk_scom.c | 212 |
1 files changed, 0 insertions, 212 deletions
diff --git a/sbe/sample/pk_scom.c b/sbe/sample/pk_scom.c deleted file mode 100644 index 2716b8d5..00000000 --- a/sbe/sample/pk_scom.c +++ /dev/null @@ -1,212 +0,0 @@ -//----------------------------------------------------------------------------- -// *! (C) Copyright International Business Machines Corp. 2014 -// *! All Rights Reserved -- Property of IBM -// *! *** IBM Confidential *** -//----------------------------------------------------------------------------- - -/// \file pk_scom.c -/// \brief Lowest level SCOM definitions. -/// -/// A fapi-level SCOM should call these functions. -/// -/// Todo: -/// - Poll PCB master for SCOM completion. -/// - Return error code of SCOM fails. -/// - Return error code if SCOM input parms violate rules. - -#include "pk.h" -#include "pk_scom.h" - -uint32_t putscom( uint32_t i_chiplet_id, uint32_t i_address, uint64_t i_data) -{ - uint32_t l_cid=0; - - // CMO-Declaring variables tied to specific registers enables us to protect - // the SCOM data and address variables used in the new stvd and lvd 64-bit - // data instructions. This protection is needed since the new instructions - // are not yet properly considered by the compiler. - // l_dataH is used to represent the "beginning" of the 64-bit data in d8 - // (i.e., r8+r9). - uint32_t register l_dataH asm("r8")=0; - uint32_t register l_dataL asm("r9")=0; - uint32_t register l_addr_eff asm("r10")=0; - uint32_t register l_scratch asm("r31")=0; - - if (i_chiplet_id) - { - // Accommodate two different ways of supplying the chiplet ID: - // 0xNN000000: Only bits in high-order two nibbles : Valid - // 0x000000NN: Only bits in low-order two nibbles : Valid - // - if ((i_chiplet_id & 0xFF000000) == i_chiplet_id) - { - // Valid: Chiplet ID in high-order two nibbles. - l_cid = i_chiplet_id; - } - else if ((i_chiplet_id & 0x000000FF) == i_chiplet_id) - { - // Valid: Chiplet ID in low-order two nibbles. Convert to high-order. - l_cid = i_chiplet_id << 24; - } - else - { - // Invalid: Invalid type of chiplet ID - PK_TRACE("putscom() : Invalid value of i_chiplet_id (=0x%08X)",i_chiplet_id); - return 1; //CMO-improve Return sensible rc here. - } - - l_addr_eff = (i_address & 0x00FFFFFF) | l_cid; - } - else - { - // Chiplet ID is zero. Accept address as is. - // This is useful for PIB addresses and non-EX chiplets, and even for - // EX chiplets if the fully qualified EX chiplet addr is already known. - l_addr_eff = i_address; - - } - - l_dataH = (uint32_t)(i_data>>32); - l_dataL = (uint32_t)(i_data); - - // CMO-The following sequence forces usage of l_dataH/L and l_addr_eff - // and thus the population of them as well. - // Further note that unless l_dataH/L are placed right before the following - // sequence, more specifically, if they're placed at the top of putscom(), - // r8, or l_dataH, might be overwritten in the if(chiplet_id) section. - // Secondly, we test l_addr_eff for non-zero through the CR0 register - // (which was populated in the "mr." instruction.) This is to convince the - // compiler that we actually used l_addr_eff for something. - // At present the test result causes no action except to execute the stvd - // instruction in either case. - asm volatile ( \ - "mr. %0, %1 \n" \ - : "=r"(l_scratch) \ - : "r"(l_dataH) ); - asm volatile ( \ - "mr. %0, %1 \n" \ - : "=r"(l_scratch) \ - : "r"(l_dataL) ); - asm volatile ( \ - "mr. %0, %1 \n" \ - : "=r"(l_scratch) \ - : "r"(l_addr_eff) ); - asm volatile ( \ - "beq 0x4 \n" ); - - -/* asm volatile ( \ - "stw %[data], 0(%[effective_address]) \n" \ - : [data]"=r"(l_dataH) \ - : [effective_address]"r"(l_addr_eff) ); -*/ - // CMO-This instruction is not fully supported by the compiler (as of - // 20150108): - // - Correct: It is correctly translated into the proper OP code - // format. - // - Incorrect: The compiler does not seem to recognize the usage - // of the two l_xyz variables in that it doesn't - // know prior to this command that the registers that - // contain the values of l_xyz need to be protected - // up to this point. Thus, we are forced to use those - // two l_xyz variables in some dummy instructions just - // before this point in order to protect them. - asm volatile ( \ - "stvd %[data], 0(%[effective_address]) \n" \ - : [data]"=r"(l_dataH) \ - : [effective_address]"r"(l_addr_eff) ); - - // CMO-TBD - // Check PIB response code in 0x00001007(17:19) - // Translate PIB rc to PK rc - // Does this rc get reset to zero on success? - // Do we need to check this rc prior to issuing the SCOM? - - return 0; -} - - -uint32_t getscom( uint32_t i_chiplet_id, uint32_t i_address, uint64_t *o_data) -{ - uint32_t l_cid=0; - - // CMO-Declaring variables tied to specific registers enables us to protect - // the SCOM data and address variables used in the new stvd and lvd 64-bit - // data instructions. This protection is needed since the new instructions - // are not yet properly considered by the compiler. - // l_dataH is used to represent the "beginning" of the 64-bit data in d8 - // (i.e., r8+r9). - uint32_t register l_dataH asm("r8")=0; - uint32_t register l_dataL asm("r9")=0; - uint32_t register l_addr_eff asm("r10")=0; - uint32_t register l_scratch asm("r31")=0; - - if (i_chiplet_id) - { - // Accommodate two different ways of supplying the chiplet ID: - // 0xNN000000: Only bits in high-order two nibbles : Valid - // 0x000000NN: Only bits in low-order two nibbles : Valid - // - if ((i_chiplet_id & 0xFF000000) == i_chiplet_id) - { - // Valid: Chiplet ID in high-order two nibbles. - l_cid = i_chiplet_id; - } - else if ((i_chiplet_id & 0x000000FF) == i_chiplet_id) - { - // Valid: Chiplet ID in low-order two nibbles. Convert to high-order. - l_cid = i_chiplet_id << 24; - } - else - { - // Invalid: Invalid type of chiplet ID - PK_TRACE("getscom() : Invalid value of i_chiplet_id (=0x%08X)",i_chiplet_id); - return 1; //CMO-improve Return sensible rc here. - } - - l_addr_eff = (i_address & 0x00FFFFFF) | l_cid; - } - else - { - // Chiplet ID is zero. Accept address as is. - // This is useful for PIB addresses and non-EX chiplets, and even for - // EX chiplets if the fully qualified EX chiplet addr is already known. - l_addr_eff = i_address; - } - - // CMO-The following sequence forces usage of l_addr_eff and thus the - // population of it as well. - // Secondly, we test l_addr_eff for non-zero through the CR0 register - // (which was populated in the "mr." instruction.) This is to convince the - // compiler that we actually used l_addr_eff for something. - // At present the test result causes no action except to execute the lvd - // instruction in either case. - asm volatile ( \ - "mr. %0, %1 \n" \ - : "=r"(l_scratch) \ - : "r"(l_addr_eff) ); - asm volatile ( \ - "beq 0x4 \n" ); - - asm volatile ( \ - "lvd %[data], 0(%[effective_address]) \n" \ - : [data]"=r"(l_dataH) \ - : [effective_address]"r"(l_addr_eff) ); - - // CMO-The following sequence moves the read data, in l_dataH/L, into the - // 64-bit o_data location. - asm volatile ( \ - "stw %0, 0(%1) \n" \ - : "=r"(l_dataH) \ - : "r"(o_data) ); - asm volatile ( \ - "stw %0, 4(%1) \n" \ - : "=r"(l_dataL) \ - : "r"(o_data) ); - - // CMO-TBD - // Check PIB response code in 0x00001007(17:19) - // Translate PIB rc to PK rc - - return 0; -} |