summaryrefslogtreecommitdiffstats
path: root/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_pore_table_gen_api_fixed.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_pore_table_gen_api_fixed.C')
-rw-r--r--src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_pore_table_gen_api_fixed.C846
1 files changed, 0 insertions, 846 deletions
diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_pore_table_gen_api_fixed.C b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_pore_table_gen_api_fixed.C
deleted file mode 100644
index 47c1afeb1..000000000
--- a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_pore_table_gen_api_fixed.C
+++ /dev/null
@@ -1,846 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_pore_table_gen_api_fixed.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2014 */
-/* [+] 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: p8_pore_table_gen_api_fixed.C,v 1.15 2014/05/30 20:31:24 cmolsen Exp $
-//
-/*------------------------------------------------------------------------------*/
-/* *! (C) Copyright International Business Machines Corp. 2012 */
-/* *! All Rights Reserved -- Property of IBM */
-/* *! *** *** */
-/*------------------------------------------------------------------------------*/
-/* *! TITLE : p8_pore_table_gen_api_fixed.C */
-/* *! DESCRIPTION : PORE SLW table generaion APIs */
-/* *! OWNER NAME : Michael Olsen Email: cmolsen@us.ibm.com */
-//
-/* *! USAGE : To build for PHYP command-line - */
-/* buildecmdprcd -C "p8_pore_table_gen_api_fixed.C" -c "p8_pore_table_static_data.c,sbe_xip_image.c,pore_inline_assembler.c" -u "SLW_COMMAND_LINE_RAM" p8_pore_table_gen_api_fixed_main.C */
-//
-/* *! COMMENTS : - The DYNAMIC_RAM_TABLE_PPD was dropped in v1.12 of this */
-/* code. See v1.12 for explanation and code implementation. */
-//
-/*------------------------------------------------------------------------------*/
-
-#define __P8_PORE_TABLE_GEN_API_C
-#include <p8_pore_api_custom.h>
-#include <p8_pore_table_gen_api.H>
-#include <p8_delta_scan_rw.h>
-
-/*
-// io_image - pointer to SLW image
-// i_modeBuild - 0: HB/IPL mode, 1: PHYP/Rebuild mode, 2: SRAM mode.
-// i_regName - unswizzled enum SPR value (NOT a name)
-// i_regData - data to write
-// i_coreIndex - core ID = [0:15]
-// i_threadIndex - thread to operate on = [0:7].
-*/
-uint32_t p8_pore_gen_cpureg_fixed( void *io_image,
- uint8_t i_modeBuild,
- uint32_t i_regName,
- uint64_t i_regData,
- uint32_t i_coreId,
- uint32_t i_threadId)
-{
- uint32_t rc=0, rcLoc=0, iCount=0;
- int i=0, iReg=-1;
- uint64_t xipSlwRamSection;
- void *hostSlwRamSection;
- void *hostSlwSectionFixed;
- uint64_t xipRamTableThis;
- void *hostRamVector;
- void *hostRamTableThis=NULL;
- void *hostRamEntryThis=NULL, *hostRamEntryNext=NULL;
- uint8_t bNewTable=0, bFound=0;
- uint8_t bEntryEnd=1, headerType=0;
- SbeXipSection xipSection;
- SbeXipItem xipTocItem;
- RamTableEntry ramEntryThis, *ramEntryNext;
- uint32_t sprSwiz=0;
-
- // -------------------------------------------------------------------------
- // Validate Ramming parameters.
- //
- // ...check mode build
- if (i_modeBuild>P8_SLW_MODEBUILD_MAX_VALUE) {
- MY_ERR("modeBuild=%i invalid. Valid range is [0;%i].",
- i_modeBuild,P8_SLW_MODEBUILD_MAX_VALUE);
- rcLoc = 1;
- }
- // ...check register value
- bFound = 0;
- for (i=0;i<SLW_SPR_REGS_SIZE;i++) {
- if (i_regName==SLW_SPR_REGS[i].value) {
- bFound = 1;
- iReg = i;
- break;
- }
- }
- if (!bFound) {
- MY_ERR("Register value = %i is not supported.\n",i_regName);
- MY_ERR("The following registers are supported:\n");
- for (i=0;i<SLW_SPR_REGS_SIZE;i++)
- MY_ERR("\t(%s,%i)\n",SLW_SPR_REGS[i].name,SLW_SPR_REGS[i].value);
- rcLoc = 1;
- }
- // ...check core ID
- if (i_coreId>=SLW_MAX_CORES) {
- MY_ERR("Core ID = %i is not within valid range of [0;%i]\n",i_coreId,SLW_MAX_CORES-1);
- rcLoc = 1;
- }
- // ...check thread ID
- // - ensure it's zero if SPR is not thread scoped, i.e. if SPR is core scoped.
- // - error out if threadId exceed max num of threads.
- if (i_regName!=P8_SPR_HSPRG0 && i_regName!=P8_SPR_LPCR && i_regName!=P8_MSR_MSR) {
- i_threadId = 0;
- }
- if (i_threadId>=SLW_CORE_THREADS) {
- MY_ERR("Thread ID = %i is not within valid range of [0;%i]\n",i_threadId,SLW_CORE_THREADS-1);
- rcLoc = 1;
- }
- if (rcLoc)
- return IMGBUILD_ERR_RAM_INVALID_PARM;
- rcLoc = 0;
-
- // -------------------------------------------------------------------------
- // Check slw section location and size. (Mainly needed for fixed image.)
- //
- if (i_modeBuild==P8_SLW_MODEBUILD_IPL ||
- i_modeBuild==P8_SLW_MODEBUILD_REBUILD) { // Fixed image.
- hostSlwSectionFixed = (void*)( (uintptr_t)io_image +
- FIXED_SLW_IMAGE_SIZE -
- FIXED_FFDC_SECTION_SIZE -
- FIXED_SLW_SECTION_SIZE );
- // Even though we shouldn't call this api during a rebuild, it should be
- // safe to do so in this particular case since none of the info requested
- // is supposed to be moved during a rebuild.
- rc = sbe_xip_get_section( io_image, SBE_XIP_SECTION_SLW, &xipSection);
- if (rc) {
- MY_ERR("Probably invalid section name for SBE_XIP_SECTION_SLW.\n");
- return IMGBUILD_ERR_GET_SECTION;
- }
- hostSlwRamSection = (void*)((uintptr_t)io_image + xipSection.iv_offset);
- if (hostSlwSectionFixed!=hostSlwRamSection) {
- MY_ERR("hostSlwSectionFixed != hostSlwRamSection(from image api).\n");
- return IMGBUILD_ERR_RAM_HDRS_NOT_SYNCED;
- }
- else {
- MY_INF("hostSlwSectionFixed == hostSlwRamSection(from image api).\n");
- }
- }
- else { // SRAM non-fixed image.
- rc = sbe_xip_get_section( io_image, SBE_XIP_SECTION_SLW, &xipSection);
- if (rc) {
- MY_ERR("Probably invalid section name for SBE_XIP_SECTION_SLW.\n");
- return IMGBUILD_ERR_GET_SECTION;
- }
- hostSlwRamSection = (void*)((uintptr_t)io_image + xipSection.iv_offset);
- sbe_xip_host2pore( io_image, hostSlwRamSection, &xipSlwRamSection);
- }
-
- // -------------------------------------------------------------------------
- // Cross check SPR register and table defines
- //
- if (SLW_SPR_REGS_SIZE!=(SLW_MAX_CPUREGS_CORE+SLW_MAX_CPUREGS_THREADS)) {
- MY_ERR("Defines in *.H header file not in sync.\n");
- return IMGBUILD_ERR_RAM_HDRS_NOT_SYNCED;
- }
- if (xipSection.iv_size!=FIXED_SLW_SECTION_SIZE) {
- MY_ERR("Fixed SLW table size in *.H header file differs from SLW section size in image.\n");
- MY_ERR("Check code or image version.\n");
- return IMGBUILD_ERR_RAM_HDRS_NOT_SYNCED;
- }
-
- // -------------------------------------------------------------------------
- // Summarize parameters and checking results.
- //
- MY_INF("Input parameter checks - OK\n");
- MY_INF("\tMode build= %i\n",i_modeBuild);
- MY_INF("\tRegister = (%s,%i)\n",SLW_SPR_REGS[iReg].name,SLW_SPR_REGS[iReg].value);
- MY_INF("\tCore ID = %i\n",i_coreId);
- MY_INF("\tThread ID = %i\n",i_threadId);
- MY_INF("Image validation and size checks - OK\n");
- MY_INF("\tSLW section size= %i\n",xipSection.iv_size);
-
- // -------------------------------------------------------------------------
- // Locate RAM vector and locate RAM table associated with "This" core ID.
- //
- if (i_modeBuild==P8_SLW_MODEBUILD_IPL ||
- i_modeBuild==P8_SLW_MODEBUILD_REBUILD) { // Fixed image.
- hostRamTableThis = (void*)( (uintptr_t)io_image +
- FIXED_SLW_IMAGE_SIZE -
- FIXED_FFDC_SECTION_SIZE -
- FIXED_SLW_SECTION_SIZE +
- SLW_RAM_TABLE_SPACE_PER_CORE*i_coreId );
- if (*(uintptr_t*)hostRamTableThis) { // Table content NOT empty.
- bNewTable = 0; // So, NOT new table.
- }
- else { // Table content empty.
- bNewTable = 1; // So, new table.
- }
- }
- else { // SRAM non-fixed image.
- rc = sbe_xip_find( io_image, SLW_HOST_REG_VECTOR_TOC_NAME, &xipTocItem);
- if (rc) {
- MY_ERR("Probably invalid key word for SLW_HOST_REG_VECTOR_TOC_NAME.\n");
- return IMGBUILD_ERR_KEYWORD_NOT_FOUND;
- }
- sbe_xip_pore2host( io_image, xipTocItem.iv_address, &hostRamVector);
- xipRamTableThis = myRev64(*((uint64_t*)hostRamVector + i_coreId));
- if (xipRamTableThis) {
- sbe_xip_pore2host( io_image, xipRamTableThis, &hostRamTableThis);
- bNewTable = 0;
- }
- else {
- hostRamTableThis = (void*)( (uintptr_t)hostSlwRamSection +
- SLW_RAM_TABLE_SPACE_PER_CORE*i_coreId );
- bNewTable = 1;
- }
- }
-
-
- // -------------------------------------------------------------------------
- // Create most of the RAM entry, so it can be used to find a potential existing entry to
- // replace. Postpone decision about bEntryEnd and assume its zero for now (not end).
- //
- if (i_regName==P8_MSR_MSR) {
- // ...make the MSR header
- headerType = 0x1; // MTMSRD header.
- ramEntryThis.header = ( ((uint32_t)headerType) << RAM_HEADER_TYPE_START_C & RAM_HEADER_TYPE_MASK_C ) |
- ( i_threadId << RAM_HEADER_THREAD_START_C & RAM_HEADER_THREAD_MASK_C );
- // ...make the MSR instr
- ramEntryThis.instr = RAM_MTMSRD_INSTR_TEMPL_C;
- }
- else {
- // ...make the SPR header
- headerType = 0x0; // MTSPR header.
- ramEntryThis.header = ( ((uint32_t)headerType) << RAM_HEADER_TYPE_START_C & RAM_HEADER_TYPE_MASK_C ) |
- ( i_regName << RAM_HEADER_SPRN_START_C & RAM_HEADER_SPRN_MASK_C ) |
- ( i_threadId << RAM_HEADER_THREAD_START_C & RAM_HEADER_THREAD_MASK_C );
- // ...make the SPR instr
- sprSwiz = i_regName>>5 | (i_regName & 0x0000001f)<<5;
- if (sprSwiz!=SLW_SPR_REGS[iReg].swizzled) {
- MY_ERR("Inconsistent swizzle rules implemented. Check code. Dumping data.\n");
- MY_ERR("\tsprSwiz (on-the-fly-calc)=%i\n",sprSwiz);
- MY_ERR("\tSLW_SPR_REGS[%i].swizzled=%i\n",iReg,SLW_SPR_REGS[iReg].swizzled);
- return IMGBUILD_ERR_RAM_CODE;
- }
- ramEntryThis.instr = RAM_MTSPR_INSTR_TEMPL_C | ( ( sprSwiz<<RAM_MTSPR_SPR_START_C ) & RAM_MTSPR_SPR_MASK_C );
- }
- // ...make the data
- ramEntryThis.data = i_regData;
-
-
-
- // -------------------------------------------------------------------------
- // Determine insertion point of new RAM entry, hostRamEntryThis. The possibilities are:
- // - New table => First entry
- // - Existing Ram entry => Replace said entry
- // - Existing table, new Ram entry => Last entry
- //
- uint8_t bReplaceEntry=0;
- uint32_t headerNext=0;
- uint32_t instrNext=0;
-
- bReplaceEntry = 0;
- if (bNewTable) {
- // Append to beginning of agreed upon static Ram table position for this coreId.
- bEntryEnd = 1;
- ramEntryThis.header = ( ((uint32_t)bEntryEnd) << RAM_HEADER_END_START_C & RAM_HEADER_END_MASK_C ) |
- ramEntryThis.header;
- hostRamEntryThis = hostRamTableThis;
- if (i_modeBuild==P8_SLW_MODEBUILD_SRAM) {
- // Update RAM vector (since it is currently NULL)
- *((uint64_t*)hostRamVector + i_coreId) =
- myRev64( xipSlwRamSection + SLW_RAM_TABLE_SPACE_PER_CORE*i_coreId );
- }
- }
- else {
- // Append at end of existing Ram table for this coreId
- // or
- // Replace an existing Ram entry
- hostRamEntryNext = hostRamTableThis;
- ramEntryNext = (RamTableEntry*)hostRamEntryNext;
- headerNext = myRev32(ramEntryNext->header);
- instrNext = myRev32(ramEntryNext->instr);
- iCount = 1;
- // Examine all entries, except last entry.
- while ((headerNext & RAM_HEADER_END_MASK_C)==0 && bReplaceEntry==0) {
- if (iCount>=SLW_MAX_CPUREGS_OPS) {
- MY_ERR("Bad table! Header end bit not found and RAM table full (=%i entries).\n",SLW_MAX_CPUREGS_OPS);
- return IMGBUILD_ERR_RAM_TABLE_END_NOT_FOUND;
- }
- if (ramEntryThis.header==headerNext && ramEntryThis.instr==instrNext) {
- // Its a replacement. Stop searching. Go do the replacement.
- bReplaceEntry = 1;
- hostRamEntryThis = hostRamEntryNext;
- }
- else {
- hostRamEntryNext = (void*)((uint8_t*)hostRamEntryNext + XIPSIZE_RAM_ENTRY);
- ramEntryNext = (RamTableEntry*)hostRamEntryNext;
- headerNext = myRev32(ramEntryNext->header);
- instrNext = myRev32(ramEntryNext->instr);
- iCount++;
- }
- }
- if (bReplaceEntry==0) {
- // Examine the last entry.
- if (headerNext & RAM_HEADER_END_MASK_C) {
- // Now we know for sure that our new Ram entry will also be the last, either as a
- // replace or append. So put the end bit into the new entry.
- bEntryEnd = 1;
- ramEntryThis.header = ( ((uint32_t)bEntryEnd) << RAM_HEADER_END_START_C & RAM_HEADER_END_MASK_C ) |
- ramEntryThis.header;
- // Determine if to replace or append.
- if (ramEntryThis.header==headerNext && ramEntryThis.instr==instrNext) {
- // Its a replacement. And it would be legal to replace the very last Ram in a completely full table.
- if (iCount<=SLW_MAX_CPUREGS_OPS) {
- bReplaceEntry = 1;
- hostRamEntryThis = hostRamEntryNext;
- }
- else {
- MY_ERR("RAM table is full. Max %i entries allowed.\n",SLW_MAX_CPUREGS_OPS);
- return IMGBUILD_ERR_RAM_TABLE_FULL;
- }
- }
- else {
- // Its an append. Make sure there's room for one more Ram entry.
- if (iCount<SLW_MAX_CPUREGS_OPS) {
- // Zero out the end bit in last entrys header (which will now be 2nd last).
- ramEntryNext->header = ramEntryNext->header & myRev32(~RAM_HEADER_END_MASK_C);
- hostRamEntryThis = (void*)((uint8_t*)hostRamEntryNext + XIPSIZE_RAM_ENTRY);
- }
- else {
- MY_ERR("RAM table is full. Max %i entries allowed.\n",SLW_MAX_CPUREGS_OPS);
- return IMGBUILD_ERR_RAM_TABLE_FULL;
- }
- }
- }
- else {
- MY_ERR("We should never get here. Check code. Dumping data:\n");
- MY_ERR("myRev32(ramEntryNext->header) = 0x%08x\n",myRev32(ramEntryNext->header));
- MY_ERR("RAM_HEADER_END_MASK_C = 0x%08x\n",RAM_HEADER_END_MASK_C);
- return IMGBUILD_ERR_RAM_CODE;
- }
- }
- }
-
-
- // Summarize new table entry data
- MY_INF("New table entry data (host format):\n");
- MY_INF("\theader = 0x%08x\n",ramEntryThis.header);
- MY_INF("\tinstr = 0x%08x\n",ramEntryThis.instr);
- MY_INF("\tdata = 0x%016llx\n",ramEntryThis.data);
-
- // -------------------------------------------------------------------------
- // Insert the new RAM entry into the table in BE format.
- //
- ramEntryNext = (RamTableEntry*)hostRamEntryThis;
- // ...some redundant checking
- if (bNewTable) {
- // For any new table, the insertion location should be clean. We check for this here.
- if (myRev32(ramEntryNext->header)!=0) {
- MY_ERR("WARNING : Table entry location should be empty for a new table. Check code and image. Dumping data:\n");
- MY_ERR("\theader = 0x%08x\n",myRev32(ramEntryNext->header));
- MY_ERR("\tinstr = 0x%08x\n",myRev32(ramEntryNext->instr));
- MY_ERR("\tdata = 0x%016llx\n",myRev64(ramEntryNext->data));
- rc = IMGBUILD_WARN_RAM_TABLE_CONTAMINATION;
- }
- }
- // ..insert the new Ram entry.
- ramEntryNext->header = myRev32(ramEntryThis.header);
- ramEntryNext->instr = myRev32(ramEntryThis.instr);
- ramEntryNext->data = myRev64(ramEntryThis.data);
-
- return rc;
-}
-
-
-/*
-// io_image - Pointer to SLW image.
-// i_modeBuild - 0: HB/IPL mode, 1: PHYP/Rebuild mode, 2: SRAM mode.
-// i_scomAddr - Scom address.
-// i_coreId - The core ID [0:15].
-// i_scomData - Data to write to scom register.
-// i_operation - What to do with the scom addr and data.
-// i_section - 0: General Scoms, 1: L2 cache, 2: L3 cache.
-*/
-uint32_t p8_pore_gen_scom_fixed(void *io_image,
- uint8_t i_modeBuild,
- uint32_t i_scomAddr,
- uint32_t i_coreId, // [0:15]
- uint64_t i_scomData,
- uint32_t i_operation, // [0:7]
- uint32_t i_section) // [0,1,2]
-{
- uint32_t rc=0, rcLoc=0, iEntry=0;
- uint32_t chipletId=0;
- uint32_t operation=0;
- uint32_t entriesCount=0, entriesMatch=0, entriesNOP=0;
- void *hostSlwSection;
- void *hostSlwSectionFixed;
- uint64_t xipScomTableThis;
- void *hostScomVector, *hostScomTableThis;
- void *hostScomEntryNext; // running entry pointer
- void *hostScomEntryMatch=NULL; // pointer to entry that matches scomAddr
- void *hostScomEntryRET=NULL; // pointer to first return instr after table
- void *hostScomEntryNOP=NULL; // pointer to first nop IIS
- uint8_t bufIIS[XIPSIZE_SCOM_ENTRY], bufNOP[4], bufRET[4];
- SbeXipSection xipSection;
- SbeXipItem xipTocItem;
- PoreInlineContext ctx;
-
- // -------------------------------------------------------------------------
- // Validate Scom parameters.
- //
- // ...check if valid Scom register (is there anything we can do here to check?)
- // Skipping check. We blindly trust caller.
- //
- // ...check mode build
- if (i_modeBuild>P8_SLW_MODEBUILD_MAX_VALUE) {
- MY_ERR("modeBuild=%i invalid. Valid range is [0;%i].",
- i_modeBuild,P8_SLW_MODEBUILD_MAX_VALUE);
- rcLoc = 1;
- }
- // ...check Scom operation
- if (i_operation<P8_PORE_SCOM_FIRST_OP || i_operation>P8_PORE_SCOM_LAST_OP) {
- MY_ERR("Scom operation = %i is not within valid range of [%d;%d]\n",
- i_operation, P8_PORE_SCOM_FIRST_OP, P8_PORE_SCOM_LAST_OP);
- rcLoc = 1;
- }
- // ...check that core ID corresponds to valid chiplet ID
- chipletId = i_coreId + P8_CID_EX_LOW;
- if (chipletId<P8_CID_EX_LOW || chipletId>P8_CID_EX_HIGH) {
- MY_ERR("Chiplet ID = 0x%02x is not within valid range of [0x%02x;0x%02x]\n",
- chipletId, P8_CID_EX_LOW, P8_CID_EX_HIGH);
- rcLoc = 1;
- }
- if (rcLoc)
- return IMGBUILD_ERR_SCOM_INVALID_PARM;
- rcLoc = 0;
-
- // -------------------------------------------------------------------------
- // Check slw section location and size. (Mainly needed for fixed image.)
- //
- if (i_modeBuild==P8_SLW_MODEBUILD_IPL ||
- i_modeBuild==P8_SLW_MODEBUILD_REBUILD) { // Fixed image.
- hostSlwSectionFixed = (void*)( (uintptr_t)io_image +
- FIXED_SLW_IMAGE_SIZE -
- FIXED_FFDC_SECTION_SIZE -
- FIXED_SLW_SECTION_SIZE );
- // Even though we shouldn't call this api during a rebuild, it should be
- // safe to do so in this particular case since none of the info requested
- // is supposed to be moved during a rebuild.
- rc = sbe_xip_get_section( io_image, SBE_XIP_SECTION_SLW, &xipSection);
- if (rc) {
- MY_ERR("Probably invalid section name for SBE_XIP_SECTION_SLW.\n");
- return IMGBUILD_ERR_GET_SECTION;
- }
- hostSlwSection = (void*)((uintptr_t)io_image + xipSection.iv_offset);
- if (hostSlwSectionFixed!=hostSlwSection) {
- MY_ERR("hostSlwSectionFixed != hostSlwSection(from image api).\n");
- return IMGBUILD_ERR_SCOM_HDRS_NOT_SYNCD;
- }
- else {
- MY_INF("hostSlwSectionFixed == hostSlwSection(from image api).\n");
- }
- }
- else { // SRAM non-fixed image.
- rc = sbe_xip_get_section( io_image, SBE_XIP_SECTION_SLW, &xipSection);
- if (rc) {
- MY_ERR("Probably invalid section name for SBE_XIP_SECTION_SLW.\n");
- return IMGBUILD_ERR_GET_SECTION;
- }
- hostSlwSection = (void*)((uintptr_t)io_image + xipSection.iv_offset);
- }
-
- // -------------------------------------------------------------------------
- // Check .slw section size and cross-check w/header define.
- //
- if (xipSection.iv_size!=FIXED_SLW_SECTION_SIZE) {
- MY_ERR("SLW table size in *.H header file (=%i) differs from SLW section size in image (=%i).\n",FIXED_SLW_SECTION_SIZE,xipSection.iv_size);
- MY_ERR("Check code or image version.\n");
- return IMGBUILD_ERR_SCOM_HDRS_NOT_SYNCD;
- }
-
- // -------------------------------------------------------------------------
- // Summarize parameters and checking results.
- //
- MY_INF("Input parameter checks - OK\n");
- MY_INF("\tRegister = 0x%08x\n",i_scomAddr);
- MY_INF("\tOperation = %i\n",i_operation);
- MY_INF("\tSection = %i\n",i_section);
- MY_INF("\tCore ID = %i\n",i_coreId);
- MY_INF("Image validation and size checks - OK\n");
- MY_INF("\tSLW section size= %i\n",xipSection.iv_size);
-
- // -------------------------------------------------------------------------
- // Locate Scom vector according to i_section and then locate Scom table
- // associated with "This" core ID.
- //
- if (i_modeBuild==P8_SLW_MODEBUILD_IPL ||
- i_modeBuild==P8_SLW_MODEBUILD_REBUILD) { // Fixed image.
- switch (i_section) {
- case P8_SCOM_SECTION_NC:
- hostScomTableThis = (void*)( (uintptr_t)hostSlwSection +
- SLW_RAM_TABLE_SIZE +
- SLW_SCOM_TABLE_SPACE_PER_CORE_NC*i_coreId );
- break;
- case P8_SCOM_SECTION_L2:
- hostScomTableThis = (void*)( (uintptr_t)hostSlwSection +
- SLW_RAM_TABLE_SIZE +
- SLW_SCOM_TABLE_SIZE_NC +
- SLW_SCOM_TABLE_SPACE_PER_CORE_L2*i_coreId );
- break;
- case P8_SCOM_SECTION_L3:
- hostScomTableThis = (void*)( (uintptr_t)hostSlwSection +
- SLW_RAM_TABLE_SIZE +
- SLW_SCOM_TABLE_SIZE_NC +
- SLW_SCOM_TABLE_SIZE_L2 +
- SLW_SCOM_TABLE_SPACE_PER_CORE_L3*i_coreId );
- break;
- default:
- MY_ERR("Invalid value for i_section (=%i).\n",i_section);
- MY_ERR("Valid values for i_section = [%i,%i,%i].\n",
- P8_SCOM_SECTION_NC,P8_SCOM_SECTION_L2,P8_SCOM_SECTION_L3);
- return IMGBUILD_ERR_SCOM_INVALID_SUBSECTION;
- break;
- }
- }
- else { // SRAM non-fixed image.
- switch (i_section) {
- case P8_SCOM_SECTION_NC:
- rc = sbe_xip_find( io_image, SLW_HOST_SCOM_NC_VECTOR_TOC_NAME, &xipTocItem);
- if (rc) {
- MY_ERR("Probably invalid key word for SLW_HOST_SCOM_NC_VECTOR_TOC_NAME.\n");
- return IMGBUILD_ERR_KEYWORD_NOT_FOUND;
- }
- break;
- case P8_SCOM_SECTION_L2:
- rc = sbe_xip_find( io_image, SLW_HOST_SCOM_L2_VECTOR_TOC_NAME, &xipTocItem);
- if (rc) {
- MY_ERR("Probably invalid key word for SLW_HOST_SCOM_L2_VECTOR_TOC_NAME.\n");
- return IMGBUILD_ERR_KEYWORD_NOT_FOUND;
- }
- break;
- case P8_SCOM_SECTION_L3:
- rc = sbe_xip_find( io_image, SLW_HOST_SCOM_L3_VECTOR_TOC_NAME, &xipTocItem);
- if (rc) {
- MY_ERR("Probably invalid key word for SLW_HOST_SCOM_L3_VECTOR_TOC_NAME.\n");
- return IMGBUILD_ERR_KEYWORD_NOT_FOUND;
- }
- break;
- default:
- MY_ERR("Invalid value for i_section (=%i).\n",i_section);
- MY_ERR("Valid values for i_section = [%i,%i,%i].\n",
- P8_SCOM_SECTION_NC,P8_SCOM_SECTION_L2,P8_SCOM_SECTION_L3);
- return IMGBUILD_ERR_SCOM_INVALID_SUBSECTION;
- }
- MY_INF("xipTocItem.iv_address = 0x%016llx\n",xipTocItem.iv_address);
- sbe_xip_pore2host( io_image, xipTocItem.iv_address, &hostScomVector);
- MY_INF("hostScomVector = 0x%016llx\n",(uint64_t)hostScomVector);
- xipScomTableThis = myRev64(*((uint64_t*)hostScomVector + i_coreId));
- MY_INF("xipScomTableThis = 0x%016llx\n",xipScomTableThis);
- if (xipScomTableThis) {
- sbe_xip_pore2host( io_image, xipScomTableThis, &hostScomTableThis);
- }
- else { // Should never be here.
- MY_ERR("Code or image bug. Scom vector table entries should never be null.\n");
- return IMGBUILD_ERR_CHECK_CODE;
- }
- }
-
- //
- // Determine where to place/do Scom action and if entry already exists.
- // Insertion rules:
- // - If entry doesn't exist, insert at first NOP. (Note that if you don't do
- // this, then the table might potentially overflow since the max table size
- // doesn't include NOP entries.)
- // - If no NOP found, insert at first RET.
- //
-
- //----------------------------------------------------------------------------
- // 1. Create search strings for addr, nop and ret.
- //----------------------------------------------------------------------------
- // Note, the following IIS will also be used in case of
- // - i_operation==append
- // - i_operation==replace
- pore_inline_context_create( &ctx, (void*)bufIIS, XIPSIZE_SCOM_ENTRY, 0, 0);
- pore_LS( &ctx, P1, chipletId);
- pore_STI( &ctx, i_scomAddr, P1, i_scomData);
- if (ctx.error > 0) {
- MY_ERR("pore_LS or _STI generated rc = %d", ctx.error);
- return IMGBUILD_ERR_PORE_INLINE_ASM;
- }
- pore_inline_context_create( &ctx, (void*)bufRET, 4, 0, 0);
- pore_RET( &ctx);
- if (ctx.error > 0) {
- MY_ERR("pore_RET generated rc = %d", ctx.error);
- return IMGBUILD_ERR_PORE_INLINE_ASM;
- }
- pore_inline_context_create( &ctx, (void*)bufNOP, 4, 0, 0);
- pore_NOP( &ctx);
- if (ctx.error > 0) {
- MY_ERR("pore_NOP generated rc = %d", ctx.error);
- return IMGBUILD_ERR_PORE_INLINE_ASM;
- }
-
- //----------------------------------------------------------------------------
- // 2. Search for addr and nop in relevant coreId table until first RET.
- //----------------------------------------------------------------------------
- // Note:
- // - We go through ALL entries until first RET instr. We MUST find a RET instr,
- // though we don't check for overrun until later. (Could be improved.)
- // - Count number of entries, incl the NOOPs, until we find an RET.
- // - The STI(+SCOM_addr) opcode is in the 2nd word of the Scom entry.
- // - For an append operation, if a NOP is found (before a RET obviously), the
- // SCOM is replacing that NNNN sequence.
- hostScomEntryNext = hostScomTableThis;
- MY_INF("hostScomEntryNext (addr): 0x%016llx\n ",(uint64_t)hostScomEntryNext);
- while (memcmp(hostScomEntryNext, bufRET, sizeof(uint32_t))) {
- entriesCount++;
- MY_INF("Number of SCOM entries: %i\n ",entriesCount);
- if (*((uint32_t*)bufIIS+1)==*((uint32_t*)hostScomEntryNext+1) && entriesMatch==0) {// +1 skips 1st word in Scom entry (which loads the PC in an LS operation.)
- hostScomEntryMatch = hostScomEntryNext;
- entriesMatch++;
- }
- if (memcmp(hostScomEntryNext, bufNOP, sizeof(uint32_t))==0 && entriesNOP==0) {
- hostScomEntryNOP = hostScomEntryNext;
- entriesNOP++;
- }
- hostScomEntryNext = (void*)((uintptr_t)hostScomEntryNext + XIPSIZE_SCOM_ENTRY);
- }
- hostScomEntryRET = hostScomEntryNext; // The last EntryNext is always the first RET.
-
- //----------------------------------------------------------------------------
- // 3. Qualify (translate) operation and IIS.
- //----------------------------------------------------------------------------
- if (i_operation==P8_PORE_SCOM_APPEND)
- {
- operation = i_operation;
- }
- else if (i_operation==P8_PORE_SCOM_REPLACE)
- {
- if (hostScomEntryMatch)
- // ... do a replace
- operation = i_operation;
- else
- // ... do an append
- operation = P8_PORE_SCOM_APPEND;
- }
- else if (i_operation==P8_PORE_SCOM_NOOP)
- {
- // ...overwrite earlier bufIIS from the search step
- pore_inline_context_create( &ctx, (void*)bufIIS, XIPSIZE_SCOM_ENTRY, 0, 0);
- pore_NOP( &ctx);
- pore_NOP( &ctx);
- pore_NOP( &ctx);
- pore_NOP( &ctx);
- if (ctx.error > 0) {
- MY_ERR("*** _NOP generated rc = %d", ctx.error);
- return IMGBUILD_ERR_PORE_INLINE_ASM;
- }
- operation = i_operation;
- }
- else if ( i_operation==P8_PORE_SCOM_AND ||
- i_operation==P8_PORE_SCOM_OR )
- {
- operation = i_operation;
- }
- else if ( i_operation==P8_PORE_SCOM_AND_APPEND )
- {
- if (hostScomEntryMatch)
- // ... do the AND on existing Scom
- operation = P8_PORE_SCOM_AND;
- else
- // ... do an append (this better be to an _AND register type)
- operation = P8_PORE_SCOM_APPEND;
- }
- else if ( i_operation==P8_PORE_SCOM_OR_APPEND )
- {
- if (hostScomEntryMatch)
- // ... do the OR on existing Scom
- operation = P8_PORE_SCOM_OR;
- else
- // ... do an append (this better be to an _OR register type)
- operation = P8_PORE_SCOM_APPEND;
- }
- else if (i_operation==P8_PORE_SCOM_RESET)
- {
- // ... create RNNN instruction sequence.
- pore_inline_context_create( &ctx, (void*)bufIIS, XIPSIZE_SCOM_ENTRY, 0, 0);
- pore_RET( &ctx);
- pore_NOP( &ctx);
- pore_NOP( &ctx);
- pore_NOP( &ctx);
- if (ctx.error > 0) {
- MY_ERR("***_RET or _NOP generated rc = %d", ctx.error);
- return IMGBUILD_ERR_PORE_INLINE_ASM;
- }
- operation = i_operation;
- }
- else
- {
- MY_ERR("Scom operation = %i is not within valid range of [%d;%d]\n",
- i_operation, P8_PORE_SCOM_FIRST_OP, P8_PORE_SCOM_LAST_OP);
- return IMGBUILD_ERR_SCOM_INVALID_PARM;
- }
-
- //----------------------------------------------------------------------------
- // 4. Check for overrun.
- //----------------------------------------------------------------------------
- // Note:
- // - An entry count exceeding the max allocated entry count will result in a code error
- // because the allocation is based on an agreed upon max number of entries and
- // therefore either the code header file needs to change or the caller is not abiding
- // by the rules.
- // - An entry count equalling the max allocated entry count is allowed for all commands
- // except the APPEND command, incl the translated REPLACE->APPEND, which will result
- // in the previously mentioned code error being returned.
- // - The table can be full but still include NOOPs. If so, we can still APPEND since
- // we append at first occurrance of a NOOP or at the end of the table (at the RET).
- switch (i_section) {
- case P8_SCOM_SECTION_NC:
- if ( ( (operation==P8_PORE_SCOM_APPEND && entriesCount==SLW_MAX_SCOMS_NC) &&
- hostScomEntryNOP==NULL ) ||
- entriesCount>SLW_MAX_SCOMS_NC )
- {
- MY_ERR("SCOM table NC is full. Max %i entries allowed.\n",SLW_MAX_SCOMS_NC);
- return IMGBUILD_ERR_CHECK_CODE;
- }
- break;
- case P8_SCOM_SECTION_L2:
- if ( ( (operation==P8_PORE_SCOM_APPEND && entriesCount==SLW_MAX_SCOMS_L2) &&
- hostScomEntryNOP==NULL ) ||
- entriesCount>SLW_MAX_SCOMS_L2 )
- {
- MY_ERR("SCOM table L2 is full. Max %i entries allowed.\n",SLW_MAX_SCOMS_L2);
- return IMGBUILD_ERR_CHECK_CODE;
- }
- break;
- case P8_SCOM_SECTION_L3:
- if ( ( (operation==P8_PORE_SCOM_APPEND && entriesCount==SLW_MAX_SCOMS_L3) &&
- hostScomEntryNOP==NULL ) ||
- entriesCount>SLW_MAX_SCOMS_L3 )
- {
- MY_ERR("SCOM table L3 is full. Max %i entries allowed.\n",SLW_MAX_SCOMS_L3);
- return IMGBUILD_ERR_CHECK_CODE;
- }
- break;
- default:
- MY_ERR("Invalid value for i_section (=%i).\n",i_section);
- MY_ERR("Valid values for i_section = [%i,%i,%i].\n",
- P8_SCOM_SECTION_NC,P8_SCOM_SECTION_L2,P8_SCOM_SECTION_L3);
- return IMGBUILD_ERR_SCOM_INVALID_SUBSECTION;
- }
-
-
- // ---------------------------------------------------------------------------
- // 5. Insert the SCOM.
- // ---------------------------------------------------------------------------
- // Assuming pre-allocated Scom table (after pre-allocated Ram table):
- // - Table is pre-filled with RNNN ISS.
- // - Each core Id has dedicated space, uniformly distributed by SLW_MAX_SCOMS_NC*
- // XIPSIZE_SCOM_ENTRY.
- // - Remember to check for more than SLW_MAX_SCOMS_NC entries!
- switch (operation) {
-
- case P8_PORE_SCOM_APPEND: // Append a Scom at first occurring NNNN or RNNN,
- if (hostScomEntryNOP) {
- // ... replace the NNNN
- MY_INF("Append at NOP\n");
- memcpy(hostScomEntryNOP,(void*)bufIIS,XIPSIZE_SCOM_ENTRY);
- }
- else if (hostScomEntryRET) {
- // ... replace the RNNN
- MY_INF("Append at RET\n");
- memcpy(hostScomEntryRET,(void*)bufIIS,XIPSIZE_SCOM_ENTRY);
- }
- else {
- // We should never be here.
- MY_ERR("In case=_SCOM_APPEND: EntryRET=NULL is impossible. Check code.\n");
- return IMGBUILD_ERR_CHECK_CODE;
- }
- break;
- case P8_PORE_SCOM_REPLACE: // Replace existing Scom with new data
- if (hostScomEntryMatch) {
- // ... do a vanilla replace
- MY_INF("Replace existing Scom\n");
- memcpy(hostScomEntryMatch,(void*)bufIIS,XIPSIZE_SCOM_ENTRY);
- }
- else {
- // We should never be here.
- MY_ERR("In case=_SCOM_REPLACE: EntryMatch=NULL is impossible. Check code.\n");
- return IMGBUILD_ERR_CHECK_CODE;
- }
- break;
- case P8_PORE_SCOM_NOOP:
- if (hostScomEntryMatch) {
- // ... do a vanilla replace
- MY_INF("Replace existing Scom w/NOPs\n");
- memcpy(hostScomEntryMatch,(void*)bufIIS,XIPSIZE_SCOM_ENTRY);
- }
- else {
- MY_ERR("No Scom entry found to replace NOOPs with.\n");
- return IMGBUILD_ERR_SCOM_ENTRY_NOT_FOUND;
- }
- break;
- case P8_PORE_SCOM_OR: // Overlay Scom data onto existing data by bitwise OR
- if (hostScomEntryMatch) {
- // ... do an OR on the data (which is the 2nd DWord in the entry)
- MY_INF("Overlay existing Scom - OR case\n");
- *((uint64_t*)hostScomEntryMatch+1) =
- *((uint64_t*)hostScomEntryMatch+1) | myRev64(i_scomData);
- }
- else {
- MY_ERR("No Scom entry found to do OR operation with.\n");
- return IMGBUILD_ERR_SCOM_ENTRY_NOT_FOUND;
- }
- break;
- case P8_PORE_SCOM_AND: // Overlay Scom data onto existing data by bitwise AND
- if (hostScomEntryMatch) {
- // ... do an AND on the data (which is the 2nd DWord in the entry)
- MY_INF("Overlay existing Scom - AND case\n");
- *((uint64_t*)hostScomEntryMatch+1) =
- *((uint64_t*)hostScomEntryMatch+1) & myRev64(i_scomData);
- }
- else {
- MY_ERR("No Scom entry found to do AND operation with.\n");
- return IMGBUILD_ERR_SCOM_ENTRY_NOT_FOUND;
- }
- break;
- case P8_PORE_SCOM_RESET: // Reset (delete) table. Refill w/RNNN ISS.
- MY_INF("Reset table\n");
- hostScomEntryNext = hostScomTableThis;
- for ( iEntry=0; iEntry<entriesCount; iEntry++) {
- memcpy( hostScomEntryNext, (void*)bufIIS, XIPSIZE_SCOM_ENTRY);
- hostScomEntryNext = (void*)((uintptr_t)hostScomEntryNext + XIPSIZE_SCOM_ENTRY);
- }
- break;
- default:
- MY_ERR("Impossible value of operation (=%i). Check code.\n",operation);
- return IMGBUILD_ERR_CHECK_CODE;
-
- } // End of switch(operation)
-
- return rc;
-}
OpenPOWER on IntegriCloud