diff options
author | Van Lee <vanlee@us.ibm.com> | 2012-06-27 23:12:29 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2012-07-12 09:54:20 -0500 |
commit | 8de05d745201752e69c646e2586122b5cf89b48d (patch) | |
tree | 5dddc2e2ad6f5c662708eb72481b170ec683a694 /src/usr/pore | |
parent | 53cc1854646f8e1b82cf94f3beec8f36ef7cd353 (diff) | |
download | talos-hostboot-8de05d745201752e69c646e2586122b5cf89b48d.tar.gz talos-hostboot-8de05d745201752e69c646e2586122b5cf89b48d.zip |
Integrate cen_sbe procedures for Grub milestone
- Enable calling istep 10 under simics with required action rules
- Update Fapiporeve HWP per code review
- Pick up latest poreve code and update per code review
- change mba_startclocks to mem_startclocks in do_sprint to sync with HB
Change-Id: Id8fb932dc8409b50d3bd04be8b99724d81c74904
RTC: 42926
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/1267
Tested-by: Jenkins Server
Reviewed-by: Brian H. Horton <brianh@linux.ibm.com>
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/pore')
37 files changed, 3371 insertions, 1617 deletions
diff --git a/src/usr/pore/fapiporeve/fapiPoreVe.C b/src/usr/pore/fapiporeve/fapiPoreVe.C index bf44a6102..e650b28a7 100644 --- a/src/usr/pore/fapiporeve/fapiPoreVe.C +++ b/src/usr/pore/fapiporeve/fapiPoreVe.C @@ -1,28 +1,29 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/pore/fapiporeve/fapiPoreVe.C $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2012 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/fapiporeve/fapiPoreVe.C $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ // -*- mode: C++; c-file-style: "linux"; -*- -// $Id: fapiPoreVe.C,v 1.22 2012/01/09 20:55:27 jeshua Exp $ -// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/fapiPoreVe.C,v $ +// $Id: fapiPoreVe.C,v 1.27 2012/04/26 21:30:31 jeshua Exp $ +// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/poreve/working/fapiporeve/fapiPoreVe.C,v $ //------------------------------------------------------------------------------ // *! (C) Copyright International Business Machines Corp. 2011 // *! All Rights Reserved -- Property of IBM @@ -63,6 +64,44 @@ //For hooks #ifndef __HOSTBOOT_MODULE #include <dlfcn.h> + +typedef struct { + char * name; + PoreRegisterOffset offset; +} poreReg_t; + +poreReg_t poreRegs[] = { + { "PORE_STATUS", PORE_STATUS }, + { "PORE_CONTROL", PORE_CONTROL }, + { "PORE_RESET", PORE_RESET }, + { "PORE_ERROR_MASK", PORE_ERROR_MASK }, + { "PORE_PRV_BASE_ADDR0", PORE_PRV_BASE_ADDR0 }, + { "PORE_PRV_BASE_ADDR1", PORE_PRV_BASE_ADDR1 }, + { "PORE_OCI_MEMORY_BASE_ADDR0", PORE_OCI_MEMORY_BASE_ADDR0 }, + { "PORE_OCI_MEMORY_BASE_ADDR1", PORE_OCI_MEMORY_BASE_ADDR1 }, + { "PORE_TABLE_BASE_ADDR", PORE_TABLE_BASE_ADDR }, + { "PORE_EXE_TRIGGER", PORE_EXE_TRIGGER }, + { "PORE_SCRATCH0", PORE_SCRATCH0 }, + { "PORE_SCRATCH1", PORE_SCRATCH1 }, + { "PORE_SCRATCH2", PORE_SCRATCH2 }, + { "PORE_IBUF_01", PORE_IBUF_01 }, + { "PORE_IBUF_2", PORE_IBUF_2 }, + { "PORE_DBG0", PORE_DBG0 }, + { "PORE_DBG1", PORE_DBG1 }, + { "PORE_PC_STACK0", PORE_PC_STACK0 }, + { "PORE_PC_STACK1", PORE_PC_STACK1 }, + { "PORE_ID_FLAGS", PORE_ID_FLAGS }, + { "PORE_DATA0", PORE_DATA0 }, + { "PORE_MEM_RELOC", PORE_MEM_RELOC }, + { "PORE_I2C_E0_PARAM", PORE_I2C_E0_PARAM }, + { "PORE_I2C_E1_PARAM", PORE_I2C_E1_PARAM }, + { "PORE_I2C_E2_PARAM", PORE_I2C_E2_PARAM }, + { "PORE_HIDDEN_STATE_0", PORE_HIDDEN_STATE_0 }, + { "PORE_HIDDEN_STATE_1", PORE_HIDDEN_STATE_1 }, + { "PORE_HIDDEN_STATE_2", PORE_HIDDEN_STATE_2 }, + { "PORE_HIDDEN_STATE_3", PORE_HIDDEN_STATE_3 }, + { "PORE_HIDDEN_STATE_4", PORE_HIDDEN_STATE_4 }, +}; #endif #include "hookmanager.H" @@ -80,22 +119,21 @@ const uint32_t MBOX_SBEVITAL_0x0005001C = 0x0005001C; //****************************************************************************** fapi::ReturnCode fapiPoreVe( const fapi::Target i_target, - std::list<uint64_t> & io_sharedObjectArgs) - + std::vector<FapiPoreVeArg *> & io_sharedObjectArgs) { - fapi::ReturnCode rc; //JDS TODO - set initial values + fapi::ReturnCode rc; PoreVe *poreve = NULL; FapiPoreVeOtherArg *pOtherArg = NULL; //---------------------------------------------------------------------- // Find the PORE type //---------------------------------------------------------------------- - std::list<uint64_t>::iterator itr; + std::vector<FapiPoreVeArg *>::iterator itr; for( itr = io_sharedObjectArgs.begin(); (itr != io_sharedObjectArgs.end()) && (poreve == NULL); itr++ ) { - FapiPoreVeArg *arg = reinterpret_cast<FapiPoreVeArg *>(*itr); + FapiPoreVeArg *arg = *itr; //---------------------------------------------------------------------- // Use PORE type and pdbgArg to create poreve @@ -104,7 +142,7 @@ fapi::ReturnCode fapiPoreVe( { FapiPoreVeOtherArg *thisArg = (FapiPoreVeOtherArg *)arg; pOtherArg = thisArg; - fapi::Target masterTarget = i_target; //JDS TODO - get this from an attribute + fapi::Target masterTarget = i_target; poreve = PoreVe::create( thisArg->iv_poreType, masterTarget, thisArg->iv_pdbgArgs ); @@ -112,8 +150,8 @@ fapi::ReturnCode fapiPoreVe( } if( poreve == NULL ) { - FAPI_ERR( "Failed to create poreve\n" ); - rc = 0xDEAD0000; + FAPI_ERR( "Failed to create poreve" ); + FAPI_SET_HWP_ERROR(rc, RC_FAPIPOREVE_FAILED_TO_CREATE_POREVE); } @@ -131,7 +169,7 @@ fapi::ReturnCode fapiPoreVe( for( itr = io_sharedObjectArgs.begin(); (itr != io_sharedObjectArgs.end()) && rc.ok(); itr++ ) { - FapiPoreVeArg *arg = reinterpret_cast<FapiPoreVeArg *>(*itr); + FapiPoreVeArg *arg = *itr; //---------------------------------------------------------------------- // Install the start state (if passed in) @@ -154,15 +192,19 @@ fapi::ReturnCode fapiPoreVe( stateArg->iv_fd = fopen( stateArg->iv_filename, "r" ); if( stateArg->iv_fd == NULL ) { - FAPI_ERR( "Failed to open state file %s\n", stateArg->iv_filename ); - rc = 0xDEAD4321; + FAPI_ERR( "Failed to open state file %s", + stateArg->iv_filename ); + // char & FILENAME = stateArg->iv_filename; + FAPI_SET_HWP_ERROR(rc, + RC_FAPIPOREVE_FAILED_TO_OPEN_STATE_FILE_FOR_READING); } else { do { char line[200]; - state_rc = fgets( line, sizeof(line), stateArg->iv_fd ); + state_rc = fgets( line, sizeof(line), + stateArg->iv_fd ); linenum++; if( state_rc != NULL ) { @@ -170,95 +212,42 @@ fapi::ReturnCode fapiPoreVe( char* reg = strtok( line, " =" ); PoreRegisterOffset reg_offset; - if( strcmp( reg, "PORE_STATUS" ) == 0 ) { - reg_offset = PORE_STATUS; - } else if( strcmp( reg, "PORE_CONTROL" ) == 0 ) { - reg_offset = PORE_CONTROL; - } else if( strcmp( reg, "PORE_RESET" ) == 0 ) { - reg_offset = PORE_RESET; - } else if( strcmp( reg, "PORE_ERROR_MASK" ) == 0 ) { - reg_offset = PORE_ERROR_MASK; - } else if( strcmp( reg, "PORE_PRV_BASE_ADDR0" ) == 0 ) { - reg_offset = PORE_PRV_BASE_ADDR0; - } else if( strcmp( reg, "PORE_PRV_BASE_ADDR1" ) == 0 ) { - reg_offset = PORE_PRV_BASE_ADDR1; - } else if( strcmp( reg, "PORE_OCI_MEMORY_BASE_ADDR0" ) == 0 ) { - reg_offset = PORE_OCI_MEMORY_BASE_ADDR0; - } else if( strcmp( reg, "PORE_OCI_MEMORY_BASE_ADDR1" ) == 0 ) { - reg_offset = PORE_OCI_MEMORY_BASE_ADDR1; - } else if( strcmp( reg, "PORE_TABLE_BASE_ADDR" ) == 0 ) { - reg_offset = PORE_TABLE_BASE_ADDR; - } else if( strcmp( reg, "PORE_EXE_TRIGGER" ) == 0 ) { - reg_offset = PORE_EXE_TRIGGER; - } else if( strcmp( reg, "PORE_SCRATCH0" ) == 0 ) { - reg_offset = PORE_SCRATCH0; - } else if( strcmp( reg, "PORE_SCRATCH1" ) == 0 ) { - reg_offset = PORE_SCRATCH1; - } else if( strcmp( reg, "PORE_SCRATCH2" ) == 0 ) { - reg_offset = PORE_SCRATCH2; - } else if( strcmp( reg, "PORE_IBUF_01" ) == 0 ) { - reg_offset = PORE_IBUF_01; - } else if( strcmp( reg, "PORE_IBUF_2" ) == 0 ) { - reg_offset = PORE_IBUF_2; - } else if( strcmp( reg, "PORE_DBG0" ) == 0 ) { - reg_offset = PORE_DBG0; - } else if( strcmp( reg, "PORE_DBG1" ) == 0 ) { - reg_offset = PORE_DBG1; - } else if( strcmp( reg, "PORE_PC_STACK0" ) == 0 ) { - reg_offset = PORE_PC_STACK0; - } else if( strcmp( reg, "PORE_PC_STACK1" ) == 0 ) { - reg_offset = PORE_PC_STACK1; - } else if( strcmp( reg, "PORE_PC_STACK2" ) == 0 ) { - reg_offset = PORE_PC_STACK2; - } else if( strcmp( reg, "PORE_ID_FLAGS" ) == 0 ) { - reg_offset = PORE_ID_FLAGS; - } else if( strcmp( reg, "PORE_DATA0" ) == 0 ) { - reg_offset = PORE_DATA0; - } else if( strcmp( reg, "PORE_MEM_RELOC" ) == 0 ) { - reg_offset = PORE_MEM_RELOC; - } else if( strcmp( reg, "PORE_I2C_E0_PARAM" ) == 0 ) { - reg_offset = PORE_I2C_E0_PARAM; - } else if( strcmp( reg, "PORE_I2C_E1_PARAM" ) == 0 ) { - reg_offset = PORE_I2C_E1_PARAM; - } else if( strcmp( reg, "PORE_I2C_E2_PARAM" ) == 0 ) { - reg_offset = PORE_I2C_E2_PARAM; - } else if( strcmp( reg, "PORE_HIDDEN_STATE_0" ) == 0) { - reg_offset = PORE_HIDDEN_STATE_0; - } else if( strcmp( reg, "PORE_HIDDEN_STATE_1" ) == 0) { - reg_offset = PORE_HIDDEN_STATE_1; - } else if( strcmp( reg, "PORE_HIDDEN_STATE_2" ) == 0) { - reg_offset = PORE_HIDDEN_STATE_2; - } else if( strcmp( reg, "PORE_HIDDEN_STATE_3" ) == 0) { - reg_offset = PORE_HIDDEN_STATE_3; - } else if( strcmp( reg, "PORE_HIDDEN_STATE_4" ) == 0) { - reg_offset = PORE_HIDDEN_STATE_4; - } else { - FAPI_ERR("Unknown reg name %s on line %i\n", - reg, linenum ); - reg = NULL; - } //strcmp reg vs regname - - if( reg != NULL ) + size_t i = 0; + while (i < (sizeof(poreRegs)/sizeof(poreReg_t))) + { + if( strcmp( reg, poreRegs[i].name ) == 0 ) + { + reg_offset = poreRegs[i].offset; + break; + } + i++; + } + + if (i != (sizeof(poreRegs)/sizeof(poreReg_t))) { //get the register value char* value = strtok( NULL, " =" ); if( value != NULL ) { - uint64_t value_64 = strtoull( value, NULL, 16 ); - ModelError me = p_state->put( reg_offset, value_64 ); - FAPI_INF( "Set %s(0x%X) to 0x%llX\n", reg, reg_offset, value_64 ); + uint64_t value_64; + value_64 = strtoull(value, NULL, 16); + ModelError me; + me = p_state->put(reg_offset,value_64); + FAPI_INF( "Set %s(0x%X) to 0x%016llX\n", + reg, reg_offset, value_64 ); if( me != ME_SUCCESS ) { - FAPI_ERR( "Model error parsing state. Errno(%i)\n", + FAPI_ERR( "Model error parsing " + "state. Errno(%i)\n", (int)me); } } else { - FAPI_ERR( "Error parsing value of %s on line %i\n", - reg, linenum ); + FAPI_ERR( "Error parsing value of %s " + "on line %i\n", reg, linenum ); } - } //if reg != NULL + } } //if state_rc != NULL } while ( state_rc != NULL ); //able to read a line fclose( stateArg->iv_fd ); @@ -266,15 +255,21 @@ fapi::ReturnCode fapiPoreVe( } else { - FAPI_INF( "State pointer was passed in, so not reading state from file\n" ); + FAPI_INF( "State pointer was passed in, " + "so not reading state from file" ); } #endif - - ModelError me = poreve->iv_pore.installState( *p_state ); - if( me != ME_SUCCESS ) + if (rc.ok()) { - FAPI_ERR( "Model error installing state. Errno(%i)\n", (int)me); - rc = 0xDEAD1400 | me; + ModelError me = poreve->iv_pore.installState( *p_state ); + if( me != ME_SUCCESS ) + { + FAPI_ERR( "Model error installing state. Errno(%i)", + (int)me); + ModelError & ERROR = me; + FAPI_SET_HWP_ERROR(rc, + RC_FAPIPOREVE_FAILED_TO_INSTALL_STATE); + } } } //if install state } //end state arg processing @@ -294,7 +289,9 @@ fapi::ReturnCode fapiPoreVe( FAPI_ERR( "dlopen() failed; See dlerror() string below\n%s\n", dlerror()); FAPI_ERR( "Failed to load hooks file\n" ); - rc = 0xDEAD0002; + // char & ERROR_STRING = dlerror(); + // char & FILENAME = thisArg->iv_filename; + FAPI_SET_HWP_ERROR(rc, RC_FAPIPOREVE_FAILED_TO_LOAD_HOOKS); } else { @@ -362,11 +359,22 @@ fapi::ReturnCode fapiPoreVe( thisArg->iv_crcEnable ); } + //PIBMEM + else if( thisArg->iv_type == ARG_PIBMEM ) + { + poreve->iv_pibmemMemory.map( thisArg->iv_base, + thisArg->iv_size, + (ACCESS_MODE_READ|ACCESS_MODE_WRITE), + thisArg->iv_data, + thisArg->iv_crcEnable ); + } + //Unknown type else if( thisArg->iv_type != ARG_OTHER ) { - FAPI_ERR( "Got an arg of an unknown type\n"); - rc = 0xDEAD0005; + FAPI_ERR( "Got an arg of an unknown type"); + FapiPoreVeArg_t const& TYPE = thisArg->iv_type; + FAPI_SET_HWP_ERROR(rc, RC_FAPIPOREVE_UNKNOWN_ARG_TYPE); } } //end memory args } //end parse options @@ -376,7 +384,7 @@ fapi::ReturnCode fapiPoreVe( //---------------------------------------------------------------------- if( pOtherArg->iv_entryPoint != NULL ) { - FAPI_INF( "Looking up entry point %s\n", pOtherArg->iv_entryPoint ); + FAPI_INF( "Looking up entry point %s", pOtherArg->iv_entryPoint ); GlobalSymbolInfo epInfo; bool symbolFound = false; @@ -386,9 +394,11 @@ fapi::ReturnCode fapiPoreVe( epInfo); if( !symbolFound || (he != HOOK_OK) ) { - FAPI_ERR( "Failed to find entry point \"%s\" in hooks file\n", - pOtherArg->iv_entryPoint); - rc = 0xDEAD2000 | he; + FAPI_ERR( "Failed to find entry point \"%s\" in hooks file. " + "HookError = %d", pOtherArg->iv_entryPoint, (int)he); + // char & POINT = pOtherArg->iv_entryPoint; + HookError & ERROR = he; + FAPI_SET_HWP_ERROR(rc, RC_FAPIPOREVE_ENTRY_POINT_NOT_FOUND); HookManager::report(); } else @@ -396,8 +406,9 @@ fapi::ReturnCode fapiPoreVe( //Make sure entry point is a valid type if( epInfo.iv_type != 'T' ) { - FAPI_ERR( "Entry point is of ivalid type %c\n", epInfo.iv_type ); - rc = 0xDEAD0007; + FAPI_ERR("Entry point is of ivalid type %c", epInfo.iv_type); + char & TYPE = epInfo.iv_type; + FAPI_SET_HWP_ERROR(rc, RC_FAPIPOREVE_INVALID_ENTRY_POINT_TYPE); } else { @@ -406,8 +417,10 @@ fapi::ReturnCode fapiPoreVe( poreve->iv_pore.setPc( epInfo.iv_address ); if( me != ME_SUCCESS ) { - FAPI_ERR( "Model error setting PC. Errno(%i)\n", (int)me); - rc = 0xDEAD1000 | me; + FAPI_ERR( "Model error setting PC. Errno(%i)", (int)me); + PoreAddress & ADDRESS = epInfo.iv_address; + ModelError & ERROR = me; + FAPI_SET_HWP_ERROR(rc, RC_FAPIPOREVE_ERROR_SETTING_PC); } } } @@ -418,7 +431,7 @@ fapi::ReturnCode fapiPoreVe( //---------------------------------------------------------------------- if( pOtherArg->iv_breakpoint != NULL ) { - FAPI_INF( "Looking up breakpoint %s\n", pOtherArg->iv_breakpoint ); + FAPI_INF( "Looking up breakpoint %s", pOtherArg->iv_breakpoint ); GlobalSymbolInfo bpInfo; bool symbolFound = false; @@ -428,9 +441,11 @@ fapi::ReturnCode fapiPoreVe( bpInfo); if( !symbolFound || (he != HOOK_OK) ) { - FAPI_ERR( "Failed to find breakpoint \"%s\" in hooks file\n", - pOtherArg->iv_breakpoint); - rc = 0xDEAD2000 | he; + FAPI_ERR( "Failed to find breakpoint \"%s\" in hooks file." + "HookError = %d", pOtherArg->iv_breakpoint, (int)he); + // char & POINT = pOtherArg->iv_breakpoint; + HookError & ERROR = he; + FAPI_SET_HWP_ERROR(rc, RC_FAPIPOREVE_BREAKPOINT_NOT_FOUND); HookManager::report(); } else @@ -438,8 +453,9 @@ fapi::ReturnCode fapiPoreVe( //Make sure break point is a valid type if( bpInfo.iv_type != 'T' ) { - FAPI_ERR( "Break point is of ivalid type %c\n", bpInfo.iv_type ); - rc = 0xDEAD0007; + FAPI_ERR("Break point is of ivalid type %c", bpInfo.iv_type); + char & TYPE = bpInfo.iv_type; + FAPI_SET_HWP_ERROR(rc, RC_FAPIPOREVE_INVALID_BREAK_POINT_TYPE); } else { @@ -448,9 +464,12 @@ fapi::ReturnCode fapiPoreVe( poreve->iv_pore.setBreakpoint( bpInfo.iv_address ); if( me != ME_SUCCESS ) { - FAPI_ERR( "Model error setting breakpoint. Errno(%i)\n", + FAPI_ERR( "Model error setting breakpoint. Errno(%i)", (int)me); - rc = 0xDEAD1000 | me; + PoreAddress & ADDRESS = bpInfo.iv_address; + ModelError & ERROR = me; + FAPI_SET_HWP_ERROR(rc, + RC_FAPIPOREVE_ERROR_SETTING_BREAKPOINT); } } } @@ -461,14 +480,16 @@ fapi::ReturnCode fapiPoreVe( //---------------------------------------------------------------------- if( pOtherArg->iv_mrr != 0 ) { - FAPI_INF( "Setting MRR to 0x%llX\n", pOtherArg->iv_mrr ); + FAPI_INF( "Setting MRR to 0x%016llX", pOtherArg->iv_mrr ); ModelError me = poreve->iv_pore.registerWrite( vsbe::PORE_MEM_RELOC, pOtherArg->iv_mrr & 0x00000003fffffc00ull, sizeof(uint64_t) ); if( me != ME_SUCCESS ) { - FAPI_ERR( "Model error setting MRR. Errno(%i)\n", (int)me); - rc = 0xDEAD3000 | me; + FAPI_ERR( "Model error setting MRR. Errno(%i)", (int)me); + uint64_t & MRR = pOtherArg->iv_mrr; + ModelError & ERROR = me; + FAPI_SET_HWP_ERROR(rc, RC_FAPIPOREVE_ERROR_SETTING_MRR); } } @@ -479,7 +500,7 @@ fapi::ReturnCode fapiPoreVe( uint64_t o_actualNumInstructionsRun = 0; int runStatus = poreve->run( pOtherArg->iv_instructionCount, o_actualNumInstructionsRun ); - FAPI_INF( "PORE ran %llu instructions, and returned status 0x%X\n", + FAPI_INF( "PORE ran %llu instructions, and returned status 0x%X", o_actualNumInstructionsRun, runStatus); if( runStatus != 0 ) @@ -487,7 +508,7 @@ fapi::ReturnCode fapiPoreVe( //Parse out each status bit if( runStatus & PORE_STATUS_HALTED ) { - FAPI_INF( "PORE is stopped at a HALT instruction\n"); + FAPI_INF( "PORE is stopped at a HALT instruction"); runStatus &= ~PORE_STATUS_HALTED; //Check the SBE VITAL reg halt code for success @@ -495,7 +516,6 @@ fapi::ReturnCode fapiPoreVe( int pib_rc; ModelError me; me = poreve->getscom(MBOX_SBEVITAL_0x0005001C, data_64, pib_rc); - if( me == ME_SUCCESS ) { if( pib_rc == 0 ) @@ -504,76 +524,86 @@ fapi::ReturnCode fapiPoreVe( uint32_t haltcode = (data_64 >> 48) & 0x0000000F; if( haltcode != 0xF ) { - FAPI_ERR( "Halt code is 0x%x (ERROR)\n", haltcode ); - rc = 0xDEAD6660 | haltcode; + FAPI_ERR( "Halt code is 0x%x (ERROR)", haltcode ); + uint32_t & ERROR = haltcode; + FAPI_SET_HWP_ERROR(rc, + RC_FAPIPOREVE_HALTED_WITH_ERROR); } else { - FAPI_INF( "Halt code is 0x%x (SUCCESS)\n",haltcode); - rc = 0; + FAPI_INF( "Halt code is 0x%x (SUCCESS)",haltcode); } } else { - FAPI_ERR("PIB error getting halt code (error code %i)\n", - pib_rc ); - rc = 0xDEAD6650 | pib_rc; + FAPI_ERR("PIB error getting halt code " + "(error code %i)", pib_rc ); + int & ERROR = pib_rc; + FAPI_SET_HWP_ERROR(rc, + RC_FAPIPOREVE_PIB_ERROR_READING_SBEVITAL); } } else { - FAPI_ERR( "Model error getting halt code (me=0x%x)\n", me ); - rc = 0xDEAD6500 | me; + FAPI_ERR( "Model error getting halt code (me=0x%x)", me ); + ModelError & ERROR = me; + FAPI_SET_HWP_ERROR(rc, + RC_FAPIPOREVE_MODEL_ERROR_GETTING_HALT_CODE); } } if( runStatus & PORE_STATUS_ERROR_HALT ) { - FAPI_ERR( "PORE is stopped due to an architected error\n"); + FAPI_ERR( "PORE is stopped due to an architected error"); runStatus &= ~PORE_STATUS_ERROR_HALT; - rc = 0xDEAD7777; + FAPI_SET_HWP_ERROR(rc, RC_FAPIPOREVE_ARCHITECTED_ERROR); + poreve->iv_pore.dump(); } if( runStatus & PORE_STATUS_HARDWARE_STOP ) { - FAPI_INF( "PORE is stopped\n"); + FAPI_INF( "PORE is stopped"); runStatus &= ~PORE_STATUS_HARDWARE_STOP; } if( runStatus & PORE_STATUS_BREAKPOINT ) { - FAPI_INF( "PORE is stopped at a breakpoint\n"); + FAPI_INF( "PORE is stopped at a breakpoint"); runStatus &= ~PORE_STATUS_BREAKPOINT; } if( runStatus & PORE_STATUS_TRAP ) { - FAPI_INF( "PORE is stopped at a TRAP instruction\n"); + FAPI_INF( "PORE is stopped at a TRAP instruction"); runStatus &= ~PORE_STATUS_TRAP; } if( runStatus & PORE_STATUS_MODEL_ERROR ) { - FAPI_ERR( "PORE is stopped due to a modeling error\n"); + FAPI_ERR( "PORE is stopped due to a modeling error"); runStatus &= ~PORE_STATUS_MODEL_ERROR; - rc = 0xDEAD0003; //JDS TODO - create a real return code + FAPI_SET_HWP_ERROR(rc, RC_FAPIPOREVE_MODELING_ERROR); + poreve->iv_pore.dump(); } if( runStatus & PORE_STATUS_DEBUG_STOP ) { - FAPI_INF( "PORE is stopped due to a user request (probably a hook)\n"); + FAPI_INF( "PORE is stopped due to a user request " + "(probably a hook)"); runStatus &= ~PORE_STATUS_DEBUG_STOP; } //If we still have bits set, we missed something if( runStatus ) { - FAPI_ERR( "PORE is stopped with an unknown status code:0x%X\n", + FAPI_ERR( "PORE is stopped with an unknown status code:0x%X", runStatus); - rc = 0xDEAD0004; //JDS TODO - create a real return code + int & STATUS = runStatus; + FAPI_SET_HWP_ERROR(rc, RC_FAPIPOREVE_UNKNOWN_STATUS_ERROR); } } else { //runStatus == 0 - FAPI_IMP( "PORE ran the requested number of instructions without hitting any stop conditions\n"); + FAPI_IMP( "PORE ran the requested number of instructions " + "without hitting any stop conditions"); } if( (pOtherArg->iv_instructionCount != RUN_UNLIMITED) && (pOtherArg->iv_instructionCount != o_actualNumInstructionsRun) ) { - FAPI_IMP( "PORE only ran %llu of the %llu instructions you requested\n", - o_actualNumInstructionsRun, + FAPI_IMP( "PORE only ran %llu of the %llu instructions you " + "requested", o_actualNumInstructionsRun, pOtherArg->iv_instructionCount ); } } //if( rc.ok() ) @@ -597,7 +627,9 @@ fapi::ReturnCode fapiPoreVe( if( stateArg->iv_fd == NULL ) { FAPI_ERR( "Unable to write state to \"%s\"\n", stateArg->iv_filename ); - rc = 0xDEAD1550; + // char & FILENAME = stateArg->iv_filename; + FAPI_SET_HWP_ERROR(rc, + RC_FAPIPOREVE_FAILED_TO_OPEN_STATE_FILE_FOR_WRITING); } else { uint64_t data_64; @@ -607,37 +639,68 @@ fapi::ReturnCode fapiPoreVe( do { - printreg(vsbe::PORE_STATUS, "PORE_STATUS = 0x%llX\n" ); - printreg(vsbe::PORE_CONTROL, "PORE_CONTROL = 0x%llX\n" ); - printreg(vsbe::PORE_RESET, "PORE_RESET = 0x%llX\n" ); - printreg(vsbe::PORE_ERROR_MASK, "PORE_ERROR_MASK = 0x%llX\n" ); - printreg(vsbe::PORE_PRV_BASE_ADDR0, "PORE_PRV_BASE_ADDR0 = 0x%llX\n" ); - printreg(vsbe::PORE_PRV_BASE_ADDR1, "PORE_PRV_BASE_ADDR1 = 0x%llX\n" ); - printreg(vsbe::PORE_OCI_MEMORY_BASE_ADDR0, "PORE_OCI_MEMORY_BASE_ADDR0 = 0x%llX\n" ); - printreg(vsbe::PORE_OCI_MEMORY_BASE_ADDR1, "PORE_OCI_MEMORY_BASE_ADDR1 = 0x%llX\n" ); - printreg(vsbe::PORE_TABLE_BASE_ADDR, "PORE_TABLE_BASE_ADDR = 0x%llX\n" ); - printreg(vsbe::PORE_EXE_TRIGGER, "PORE_EXE_TRIGGER = 0x%llX\n" ); - printreg(vsbe::PORE_SCRATCH0, "PORE_SCRATCH0 = 0x%llX\n" ); - printreg(vsbe::PORE_SCRATCH1, "PORE_SCRATCH1 = 0x%llX\n" ); - printreg(vsbe::PORE_SCRATCH2, "PORE_SCRATCH2 = 0x%llX\n" ); - printreg(vsbe::PORE_IBUF_01, "PORE_IBUF_01 = 0x%llX\n" ); - printreg(vsbe::PORE_IBUF_2, "PORE_IBUF_2 = 0x%llX\n" ); - printreg(vsbe::PORE_DBG0, "PORE_DBG0 = 0x%llX\n" ); - printreg(vsbe::PORE_DBG1, "PORE_DBG1 = 0x%llX\n" ); - printreg(vsbe::PORE_PC_STACK0, "PORE_PC_STACK0 = 0x%llX\n" ); - printreg(vsbe::PORE_PC_STACK1, "PORE_PC_STACK1 = 0x%llX\n" ); - printreg(vsbe::PORE_PC_STACK2, "PORE_PC_STACK2 = 0x%llX\n" ); - printreg(vsbe::PORE_ID_FLAGS, "PORE_ID_FLAGS = 0x%llX\n" ); - printreg(vsbe::PORE_DATA0, "PORE_DATA0 = 0x%llX\n" ); - printreg(vsbe::PORE_MEM_RELOC, "PORE_MEM_RELOC = 0x%llX\n" ); - printreg(vsbe::PORE_I2C_E0_PARAM, "PORE_I2C_E0_PARAM = 0x%llX\n" ); - printreg(vsbe::PORE_I2C_E1_PARAM, "PORE_I2C_E1_PARAM = 0x%llX\n" ); - printreg(vsbe::PORE_I2C_E2_PARAM, "PORE_I2C_E2_PARAM = 0x%llX\n" ); - printreg(vsbe::PORE_HIDDEN_STATE_0, "PORE_HIDDEN_STATE_0 = 0x%llX\n" ); - printreg(vsbe::PORE_HIDDEN_STATE_1, "PORE_HIDDEN_STATE_1 = 0x%llX\n" ); - printreg(vsbe::PORE_HIDDEN_STATE_2, "PORE_HIDDEN_STATE_2 = 0x%llX\n" ); - printreg(vsbe::PORE_HIDDEN_STATE_3, "PORE_HIDDEN_STATE_3 = 0x%llX\n" ); - printreg(vsbe::PORE_HIDDEN_STATE_4, "PORE_HIDDEN_STATE_4 = 0x%llX\n" ); + printreg(vsbe::PORE_STATUS, + "PORE_STATUS = 0x%016llX\n" ); + printreg(vsbe::PORE_CONTROL, + "PORE_CONTROL = 0x%016llX\n" ); + printreg(vsbe::PORE_RESET, + "PORE_RESET = 0x%016llX\n" ); + printreg(vsbe::PORE_ERROR_MASK, + "PORE_ERROR_MASK = 0x%016llX\n" ); + printreg(vsbe::PORE_PRV_BASE_ADDR0, + "PORE_PRV_BASE_ADDR0 = 0x%016llX\n" ); + printreg(vsbe::PORE_PRV_BASE_ADDR1, + "PORE_PRV_BASE_ADDR1 = 0x%016llX\n" ); + printreg(vsbe::PORE_OCI_MEMORY_BASE_ADDR0, + "PORE_OCI_MEMORY_BASE_ADDR0 = 0x%016llX\n" ); + printreg(vsbe::PORE_OCI_MEMORY_BASE_ADDR1, + "PORE_OCI_MEMORY_BASE_ADDR1 = 0x%016llX\n" ); + printreg(vsbe::PORE_TABLE_BASE_ADDR, + "PORE_TABLE_BASE_ADDR = 0x%016llX\n" ); + printreg(vsbe::PORE_EXE_TRIGGER, + "PORE_EXE_TRIGGER = 0x%016llX\n" ); + printreg(vsbe::PORE_SCRATCH0, + "PORE_SCRATCH0 = 0x%016llX\n" ); + printreg(vsbe::PORE_SCRATCH1, + "PORE_SCRATCH1 = 0x%016llX\n" ); + printreg(vsbe::PORE_SCRATCH2, + "PORE_SCRATCH2 = 0x%016llX\n" ); + printreg(vsbe::PORE_IBUF_01, + "PORE_IBUF_01 = 0x%016llX\n" ); + printreg(vsbe::PORE_IBUF_2, + "PORE_IBUF_2 = 0x%016llX\n" ); + printreg(vsbe::PORE_DBG0, + "PORE_DBG0 = 0x%016llX\n" ); + printreg(vsbe::PORE_DBG1, + "PORE_DBG1 = 0x%016llX\n" ); + printreg(vsbe::PORE_PC_STACK0, + "PORE_PC_STACK0 = 0x%016llX\n" ); + printreg(vsbe::PORE_PC_STACK1, + "PORE_PC_STACK1 = 0x%016llX\n" ); + printreg(vsbe::PORE_PC_STACK2, + "PORE_PC_STACK2 = 0x%016llX\n" ); + printreg(vsbe::PORE_ID_FLAGS, + "PORE_ID_FLAGS = 0x%016llX\n" ); + printreg(vsbe::PORE_DATA0, + "PORE_DATA0 = 0x%016llX\n" ); + printreg(vsbe::PORE_MEM_RELOC, + "PORE_MEM_RELOC = 0x%016llX\n" ); + printreg(vsbe::PORE_I2C_E0_PARAM, + "PORE_I2C_E0_PARAM = 0x%016llX\n" ); + printreg(vsbe::PORE_I2C_E1_PARAM, + "PORE_I2C_E1_PARAM = 0x%016llX\n" ); + printreg(vsbe::PORE_I2C_E2_PARAM, + "PORE_I2C_E2_PARAM = 0x%016llX\n" ); + printreg(vsbe::PORE_HIDDEN_STATE_0, + "PORE_HIDDEN_STATE_0 = 0x%016llX\n" ); + printreg(vsbe::PORE_HIDDEN_STATE_1, + "PORE_HIDDEN_STATE_1 = 0x%016llX\n" ); + printreg(vsbe::PORE_HIDDEN_STATE_2, + "PORE_HIDDEN_STATE_2 = 0x%016llX\n" ); + printreg(vsbe::PORE_HIDDEN_STATE_3, + "PORE_HIDDEN_STATE_3 = 0x%016llX\n" ); + printreg(vsbe::PORE_HIDDEN_STATE_4 + , "PORE_HIDDEN_STATE_4 = 0x%016llX\n" ); } while (0); stateArg->iv_data=p_state; fclose( stateArg->iv_fd ); @@ -646,8 +709,8 @@ fapi::ReturnCode fapiPoreVe( #endif if( me != ME_SUCCESS ) { - FAPI_ERR( "Model error extracting state. Errno(%i)\n", (int)me); - rc = 0xDEAD1600 | me; + FAPI_ERR( "Model error extracting state. Errno(%i)", (int)me); + FAPI_SET_HWP_ERROR(rc, RC_FAPIPOREVE_ERROR_EXTRACTING_STATE); } } //if extract state @@ -669,6 +732,21 @@ 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 are included here. $Log: fapiPoreVe.C,v $ +Revision 1.27 2012/04/26 21:30:31 jeshua +file renamed from ../../../fapiporeve/working/fapiPoreVe.C to fapiPoreVe.C + +Revision 1.26 2012/04/26 20:52:47 jeshua +file renamed from ../../chips/p8/working/procedures/fapiPoreVe.C to fapiPoreVe.C + +Revision 1.25 2012/04/26 14:53:12 jeshua +Use fapi error code generation + +Revision 1.24 2012/03/01 20:11:31 jeshua +Updated for PIBMEM support + +Revision 1.23 2012/03/01 17:08:22 jeshua +Added a pore dump call on model errors and architected errors + Revision 1.22 2012/01/09 20:55:27 jeshua Don't include file-related code for hostboot diff --git a/src/usr/pore/fapiporeve/fapiPoreVeArg.C b/src/usr/pore/fapiporeve/fapiPoreVeArg.C index 43deb3499..96838432b 100644 --- a/src/usr/pore/fapiporeve/fapiPoreVeArg.C +++ b/src/usr/pore/fapiporeve/fapiPoreVeArg.C @@ -1,28 +1,29 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/pore/fapiporeve/fapiPoreVeArg.C $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2012 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/fapiporeve/fapiPoreVeArg.C $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ // -*- mode: C++; c-file-style: "linux"; -*- -// $Id: fapiPoreVeArg.C,v 1.16 2012/01/09 20:55:57 jeshua Exp $ -// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/fapiPoreVeArg.C,v $ +// $Id: fapiPoreVeArg.C,v 1.19 2012/04/26 21:30:40 jeshua Exp $ +// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/poreve/working/fapiporeve/fapiPoreVeArg.C,v $ //------------------------------------------------------------------------------ // *! (C) Copyright International Business Machines Corp. 2011 // *! All Rights Reserved -- Property of IBM @@ -74,27 +75,28 @@ FapiPoreVeMemArg::FapiPoreVeMemArg( const FapiPoreVeArg_t i_type, uint32_t rc = 0; if( iv_fd < 0 ) { - FAPI_ERR( "Failed to open %s file\n", iv_filename ); + FAPI_ERR( "Failed to open %s file", iv_filename ); rc = BAD_ERROR_CODE; } else { iv_size = lseek( iv_fd, 0, SEEK_END ); if( iv_size == (size_t)((off_t)-1) ) { - FAPI_ERR( "Failed to determine the size of %s file\n", iv_filename ); + FAPI_ERR( "Failed to determine the size of %s file", iv_filename ); } else { if( (iv_type == ARG_SRAM) || (iv_type == ARG_MAINMEM) || - (iv_type == ARG_PNOR) || (iv_type == ARG_SEEPROM) ) { - iv_data = mmap( 0, iv_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, iv_fd, 0 ); + (iv_type == ARG_PNOR) || (iv_type == ARG_SEEPROM) || + (iv_type == ARG_PIBMEM) ) { + iv_data = mmap( 0, iv_size, + PROT_READ | PROT_WRITE, MAP_PRIVATE, iv_fd, 0 ); } else { iv_data = mmap( 0, iv_size, PROT_READ, MAP_PRIVATE, iv_fd, 0 ); } if( iv_data == MAP_FAILED ) { - FAPI_ERR( "Failed to map %s file\n", iv_filename ); + FAPI_ERR( "Failed to map %s file", iv_filename ); rc = BAD_ERROR_CODE; } } } //JDS TODO - how do I make the constructor fail if mapping failed? - } #endif @@ -125,16 +127,15 @@ FapiPoreVeMemArg::~FapiPoreVeMemArg( ) rc = BAD_ERROR_CODE; } } - if( iv_fd >= 0 ) { + if( iv_filename != NULL ) { int close_rc = close( iv_fd ); if( close_rc != 0 ) { - FAPI_ERR( "Failed to close %s\n", iv_filename ); + FAPI_ERR( "Failed to close %s, iv_fd=%i\n", iv_filename, iv_fd ); rc = BAD_ERROR_CODE; } } #endif //JDS TODO - how do I make the destructor fail if unmapping failed? - } #ifndef __HOSTBOOT_MODULE @@ -203,6 +204,15 @@ 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 are included here. $Log: fapiPoreVeArg.C,v $ +Revision 1.19 2012/04/26 21:30:40 jeshua +file renamed from ../../../fapiporeve/working/fapiPoreVeArg.C to fapiPoreVeArg.C + +Revision 1.18 2012/04/26 20:53:57 jeshua +file renamed from ../../chips/p8/working/procedures/fapiPoreVeArg.C to fapiPoreVeArg.C + +Revision 1.17 2012/03/01 20:11:31 jeshua +Updated for PIBMEM support + Revision 1.16 2012/01/09 20:55:57 jeshua Don't include file-related code for hostboot diff --git a/src/usr/pore/fapiporeve/fapiPoreVeArg.H b/src/usr/pore/fapiporeve/fapiPoreVeArg.H index 8b2b0a9a8..725394871 100644 --- a/src/usr/pore/fapiporeve/fapiPoreVeArg.H +++ b/src/usr/pore/fapiporeve/fapiPoreVeArg.H @@ -1,28 +1,29 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/pore/fapiporeve/fapiPoreVeArg.H $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2012 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/fapiporeve/fapiPoreVeArg.H $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ // -*- mode: C++; c-file-style: "linux"; -*- -// $Id: fapiPoreVeArg.H,v 1.11 2011/12/07 22:31:39 jeshua Exp $ -// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/fapiPoreVeArg.H,v $ +// $Id: fapiPoreVeArg.H,v 1.14 2012/04/26 21:30:49 jeshua Exp $ +// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/poreve/working/fapiporeve/fapiPoreVeArg.H,v $ //------------------------------------------------------------------------------ // *! (C) Copyright International Business Machines Corp. 2011 // *! All Rights Reserved -- Property of IBM @@ -54,6 +55,7 @@ namespace vsbe ARG_SEEPROM, ARG_SRAM, ARG_MAINMEM, + ARG_PIBMEM, }; const uint32_t BAD_ERROR_CODE = 0xDEADC0DE; @@ -148,6 +150,15 @@ 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 are included here. $Log: fapiPoreVeArg.H,v $ +Revision 1.14 2012/04/26 21:30:49 jeshua +file renamed from ../../../fapiporeve/working/fapiPoreVeArg.H to fapiPoreVeArg.H + +Revision 1.13 2012/04/26 20:54:22 jeshua +file renamed from ../../chips/p8/working/procedures/fapiPoreVeArg.H to fapiPoreVeArg.H + +Revision 1.12 2012/03/01 20:11:31 jeshua +Updated for PIBMEM support + Revision 1.11 2011/12/07 22:31:39 jeshua Initial MRR support diff --git a/src/usr/pore/fapiporeve/fapiPoreVe_errors.xml b/src/usr/pore/fapiporeve/fapiPoreVe_errors.xml new file mode 100644 index 000000000..c0b0a2b83 --- /dev/null +++ b/src/usr/pore/fapiporeve/fapiPoreVe_errors.xml @@ -0,0 +1,176 @@ +<!-- IBM_PROLOG_BEGIN_TAG + This is an automatically generated prolog. + + $Source: src/usr/pore/fapiporeve/fapiPoreVe_errors.xml $ + + IBM CONFIDENTIAL + + COPYRIGHT International Business Machines Corp. 2012 + + p1 + + Object Code Only (OCO) source materials + Licensed Internal Code Source Materials + IBM HostBoot Licensed Internal Code + + The source code for this program is not published or other- + wise divested of its trade secrets, irrespective of what has + been deposited with the U.S. Copyright Office. + + Origin: 30 + + IBM_PROLOG_END_TAG --> +<!-- Error definitions for fapiPoreVe procedure --> +<hwpErrors> + <!-- *********************************************************************** --> + <hwpError> + <rc>RC_FAPIPOREVE_FAILED_TO_CREATE_POREVE</rc> + <description>Creation of the poreve object failed</description> + </hwpError> + <hwpError> + <rc>RC_FAPIPOREVE_FAILED_TO_OPEN_STATE_FILE_FOR_READING</rc> + <description>Failed to open the state file for reading</description> + <!--ffdc>FILENAME</ffdc--> + </hwpError> + <hwpError> + <rc>RC_FAPIPOREVE_FAILED_TO_INSTALL_STATE</rc> + <description>Got a model error installing the state</description> + <ffdc>ERROR</ffdc> + </hwpError> + <hwpError> + <rc>RC_FAPIPOREVE_FAILED_TO_LOAD_HOOKS</rc> + <description>Error loading the hooks file</description> + <!--ffdc>ERROR_STRING</ffdc--> + <!--ffdc>FILENAME</ffdc--> + </hwpError> + <hwpError> + <rc>RC_FAPIPOREVE_UNKNOWN_ARG_TYPE</rc> + <description>Found an unknown arg type</description> + <ffdc>TYPE</ffdc> + </hwpError> + <hwpError> + <rc>RC_FAPIPOREVE_ENTRY_POINT_NOT_FOUND</rc> + <description>Didn't find the entry point in the hooks file</description> + <!--ffdc>POINT</ffdc--> + <ffdc>ERROR</ffdc> + </hwpError> + <hwpError> + <rc>RC_FAPIPOREVE_INVALID_ENTRY_POINT_TYPE</rc> + <description>Entry point is an invalid type</description> + <ffdc>TYPE</ffdc> + </hwpError> + <hwpError> + <rc>RC_FAPIPOREVE_ERROR_SETTING_PC</rc> + <description>Error setting the program counter</description> + <ffdc>ADDRESS</ffdc> + <ffdc>ERROR</ffdc> + </hwpError> + <hwpError> + <rc>RC_FAPIPOREVE_BREAKPOINT_NOT_FOUND</rc> + <description>Unable to find the breakpoint in the hooks file</description> + <!--ffdc>POINT</ffdc--> + <ffdc>ERROR</ffdc> + </hwpError> + <hwpError> + <rc>RC_FAPIPOREVE_INVALID_BREAK_POINT_TYPE</rc> + <description>Break point is an invalid type</description> + <ffdc>TYPE</ffdc> + </hwpError> + <hwpError> + <rc>RC_FAPIPOREVE_ERROR_SETTING_BREAKPOINT</rc> + <description>Error setting the break point</description> + <ffdc>ADDRESS</ffdc> + <ffdc>ERROR</ffdc> + </hwpError> + <hwpError> + <rc>RC_FAPIPOREVE_ERROR_SETTING_MRR</rc> + <description>Unable to set the MRR</description> + <ffdc>MRR</ffdc> + <ffdc>ERROR</ffdc> + </hwpError> + <hwpError> + <rc>RC_FAPIPOREVE_HALTED_WITH_ERROR</rc> + <description>The SBE halted witohut setting the haltcode to success</description> + <ffdc>ERROR</ffdc> + </hwpError> + <hwpError> + <rc>RC_FAPIPOREVE_PIB_ERROR_READING_SBEVITAL</rc> + <description>Got a PIB error trying to read the SBE vital register for the halt code</description> + <ffdc>ERROR</ffdc> + </hwpError> + <hwpError> + <rc>RC_FAPIPOREVE_MODEL_ERROR_GETTING_HALT_CODE</rc> + <description>Got a model error trying to read the SBE vital register for the halt code</description> + <ffdc>ERROR</ffdc> + </hwpError> + <hwpError> + <rc>RC_FAPIPOREVE_ARCHITECTED_ERROR</rc> + <description>SBE stopped due to an architected error</description> + </hwpError> + <hwpError> + <rc>RC_FAPIPOREVE_MODELING_ERROR</rc> + <description>SBE stopped due to a modeling error</description> + </hwpError> + <hwpError> + <rc>RC_FAPIPOREVE_UNKNOWN_STATUS_ERROR</rc> + <description>SBE stopped with unknown status bits set</description> + <ffdc>STATUS</ffdc> + </hwpError> + <hwpError> + <rc>RC_FAPIPOREVE_FAILED_TO_OPEN_STATE_FILE_FOR_WRITING</rc> + <description>Failed to open the state file for writing</description> + <!--ffdc>FILENAME</ffdc--> + </hwpError> + <hwpError> + <rc>RC_FAPIPOREVE_ERROR_EXTRACTING_STATE</rc> + <description>Model error extracting state</description> + </hwpError> + <hwpError> + <rc>RC_POREVE_PIB2CFAM_ME_NOT_MAPPED_IN_MEMORY</rc> + <description>pib2cfam error. Not mapped in memory</description> + </hwpError> + <hwpError> + <rc>RC_POREVE_PIB2CFAM_ME_BUS_SLAVE_PERMISSION_DENIED</rc> + <description>Bus slave permission denied</description> + </hwpError> + <hwpError> + <rc>RC_POREVE_FASTI2C_OPERATION_ERROR</rc> + <description>Fasti2c operation error</description> + </hwpError> + <hwpError> + <rc>RC_POREVE_BUS_ME_NOT_MAPPED_IN_BUS</rc> + <description>Bus error. Not mapped in bus</description> + </hwpError> + <hwpError> + <rc>RC_POREVE_ME_NO_BUS_MODEL</rc> + <description>Error. No pibmaster bus model</description> + </hwpError> + <hwpError> + <rc>RC_POREVE_LPC_OPERATION_ERROR</rc> + <description>Lpc operation error</description> + </hwpError> + <hwpError> + <rc>RC_POREVE_PIBMEM_OPERATION_ERROR</rc> + <description>pibmem operation error</description> + </hwpError> + <hwpError> + <rc>RC_POREVE_BUS_OPERATION_ERROR</rc> + <description>bus operation error</description> + </hwpError> + <hwpError> + <rc>RC_POREVE_BUS_OCI_SLAVE_READ_NOT_SUPPORTED</rc> + <description>OCI slave read not supported</description> + </hwpError> + <hwpError> + <rc>RC_POREVE_BUS_OCI_SLAVE_WRITE_NOT_SUPPORTED</rc> + <description>OCI slave read not supported</description> + </hwpError> + <hwpError> + <rc>RC_POREVE_PIBMEM_BAD_MODE</rc> + <description>Bad Mode specified in pibmem transaction</description> + </hwpError> + <hwpError> + <rc>RC_POREVE_PIBMEM_BAD_OFFSET</rc> + <description>Bad Offset specified in pibmem transaction</description> + </hwpError> +</hwpErrors> diff --git a/src/usr/pore/poreve/makefile b/src/usr/pore/poreve/makefile index b1a2b0b89..284de12f5 100644 --- a/src/usr/pore/poreve/makefile +++ b/src/usr/pore/poreve/makefile @@ -1,11 +1,11 @@ -# IBM_PROLOG_BEGIN_TAG +# IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # -# $Source: src/usr/pore/pore_model/makefile $ +# $Source: src/usr/pore/poreve/makefile $ # # IBM CONFIDENTIAL # -# COPYRIGHT International Business Machines Corp. 2011 +# COPYRIGHT International Business Machines Corp. 2011-2012 # # p1 # @@ -19,8 +19,7 @@ # # Origin: 30 # -# IBM_PROLOG_END - +# IBM_PROLOG_END_TAG # Module poreve built from 3 different source code areas: # # model The source code of the PoreInterface and PoreModel classes, @@ -45,14 +44,14 @@ EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/plat EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/hwp EXTRAINCDIR += ${ROOTPATH}/src/usr/pore/poreve/porevesrc -CUSTOMFLAGS += -D__BYTE_ORDER=1 -D__BIG_ENDIAN=1 -D__LITTLE_ENDIAN=0 -DFASTI2C_BASE_OFFSET=0 -DDEBUG_FASTI2C=1 -D_BIG_ENDIAN=1 +CUSTOMFLAGS += -DDEBUG_FASTI2C=1 -D_BIG_ENDIAN=1 # Override to use C++ compiler for %.c/h files CC_OVERRIDE = 1 OBJS = poreveutil.o OBJS += transaction.o poreaddress.o poremodel.o poreregister.o poreinterface.o porestate.o -OBJS += pore_model.o pore_bus.o pore_fi2c.o pore_inline_decode.o vsbe.o +OBJS += pore_model.o pore_bus.o pore_fi2c.o pore_inline_decode.o vsbe.o pibmem.o OBJS += pore.o bus.o hookmanager.o poreve.o pib2cfam.o fasti2c.o sbevital.o create.o HOOK_SOURCE_FILES = $(notdir $(wildcard ./hook/*sbe*.hooks.cc)) OBJS += $(patsubst %.cc,%.o,$(HOOK_SOURCE_FILES)) diff --git a/src/usr/pore/poreve/model/bebits.H b/src/usr/pore/poreve/model/bebits.H index 403dbe53a..5d87efb83 100644 --- a/src/usr/pore/poreve/model/bebits.H +++ b/src/usr/pore/poreve/model/bebits.H @@ -1,25 +1,26 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/pore/poreve/model/bebits.H $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2012 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/poreve/model/bebits.H $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ #ifndef __VSBE_BEBITS_H #define __VSBE_BEBITS_H @@ -28,7 +29,6 @@ /// \file bebits.H /// \brief Bit manipulation for Big-Endian data - /// A bit mask for a range of bits in a big-endian uint64_t #define BE64_MASK(begin, end) \ ((0xffffffffffffffffull >> (64 - ((end) - (begin) + 1))) << (63 - (end))) diff --git a/src/usr/pore/poreve/model/modelerror.H b/src/usr/pore/poreve/model/modelerror.H index 41d42687e..4500317c5 100644 --- a/src/usr/pore/poreve/model/modelerror.H +++ b/src/usr/pore/poreve/model/modelerror.H @@ -1,29 +1,30 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/pore/poreve/model/modelerror.H $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2012 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/poreve/model/modelerror.H $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ #ifndef __VSBE_MODELERROR_H #define __VSBE_MODELERROR_H -// $Id: modelerror.H,v 1.9 2011/07/07 03:51:52 bcbrock Exp $ +// $Id: modelerror.H,v 1.10 2012/06/18 13:56:56 bcbrock Exp $ /// \file modelerror.H /// \brief An enumeration of modeling errors @@ -64,9 +65,9 @@ namespace vsbe { ME_PORE_MODEL_GENERIC_ERROR = 8, /// A transaction size error ME_SIZE_ERROR = 9, - /// An error ocurred on the registerRead() method + /// An error ocurred on the registerRead[Raw]() method ME_REGISTER_READ_ERROR = 10, - /// An error ocurred on the registerWrite() method + /// An error ocurred on the registerWrite[Raw]() method ME_REGISTER_WRITE_ERROR = 11, /// Transaction address is not in any known memory map ME_NOT_MAPPED_ON_BUS = 12, diff --git a/src/usr/pore/poreve/model/poreaddress.C b/src/usr/pore/poreve/model/poreaddress.C index 84bcaeeee..e31ed9535 100644 --- a/src/usr/pore/poreve/model/poreaddress.C +++ b/src/usr/pore/poreve/model/poreaddress.C @@ -1,25 +1,26 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/pore/poreve/model/poreaddress.C $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2012 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/poreve/model/poreaddress.C $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ // $Id: poreaddress.C,v 1.1 2011/06/08 13:12:50 bcbrock Exp $ /// \file poreaddress.C @@ -34,9 +35,8 @@ using namespace vsbe; // PoreAddress //////////////////////////////////////////////////////////////////////////// -PoreAddress::PoreAddress() +PoreAddress::PoreAddress() : iv_offset(0), iv_memorySpace(0) { - } diff --git a/src/usr/pore/poreve/model/poreinterface.C b/src/usr/pore/poreve/model/poreinterface.C index 6adef3b60..5f7e6e23b 100644 --- a/src/usr/pore/poreve/model/poreinterface.C +++ b/src/usr/pore/poreve/model/poreinterface.C @@ -1,26 +1,27 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/pore/poreve/model/poreinterface.C $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2012 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END -// $Id: poreinterface.C,v 1.7 2011/10/12 19:55:53 bcbrock Exp $ +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/poreve/model/poreinterface.C $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ +// $Id: poreinterface.C,v 1.9 2012/06/18 13:56:57 bcbrock Exp $ /// \file poreinterface.C /// \brief The PORE hardware interface class @@ -204,6 +205,24 @@ PoreInterface::getStopCode() } +ModelError +PoreInterface::getmemInteger(const PoreAddress i_address, + uint64_t& o_data, + const size_t i_size) +{ + return iv_model->getmemInteger(i_address, o_data, i_size); +} + + +ModelError +PoreInterface::putmemInteger(const PoreAddress i_address, + uint64_t i_data, + const size_t i_size) +{ + return iv_model->putmemInteger(i_address, i_data, i_size); +} + + PoreInterface::PoreInterface(PoreIbufId i_id) : d0(this, PORE_D0), d1(this, PORE_D1), @@ -230,13 +249,15 @@ PoreInterface::~PoreInterface() } +// The model is always restarted after creation to insure that the model is in +// the correct flush state. + void PoreInterface::newModel(PoreIbufId i_id) { delete iv_model; iv_model = PoreModel::create(i_id, this); iv_ibufId = i_id; + iv_model->restart(); } - - diff --git a/src/usr/pore/poreve/model/poreinterface.H b/src/usr/pore/poreve/model/poreinterface.H index 9c8b44974..cf98b31ac 100644 --- a/src/usr/pore/poreve/model/poreinterface.H +++ b/src/usr/pore/poreve/model/poreinterface.H @@ -1,29 +1,30 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/pore/poreve/model/poreinterface.H $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2012 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/poreve/model/poreinterface.H $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ #ifndef __VSBE_POREINTERFACE_H #define __VSBE_POREINTERFACE_H -// $Id: poreinterface.H,v 1.10 2011/11/07 23:39:33 bcbrock Exp $ +// $Id: poreinterface.H,v 1.11 2012/06/18 13:56:57 bcbrock Exp $ /// \file poreinterface.H /// \brief The PORE hardware interface class @@ -178,6 +179,18 @@ public: virtual int getStopCode(); + /// See PoreModel::getmemInteger() + virtual ModelError + getmemInteger(const PoreAddress i_address, + uint64_t& o_data, + const size_t i_size); + + /// See PoreModel::putmemInteger() + virtual ModelError + putmemInteger(const PoreAddress i_address, + uint64_t i_data, + const size_t i_size); + //////////////////// Abstract Interface ///////////////////////// diff --git a/src/usr/pore/poreve/model/poremodel.C b/src/usr/pore/poreve/model/poremodel.C index dfa8cbbbc..de4c020bc 100644 --- a/src/usr/pore/poreve/model/poremodel.C +++ b/src/usr/pore/poreve/model/poremodel.C @@ -1,26 +1,27 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/pore/poreve/model/poremodel.C $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2012 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END -// $Id: poremodel.C,v 1.19 2011/11/11 00:50:35 bcbrock Exp $ +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/poreve/model/poremodel.C $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ +// $Id: poremodel.C,v 1.22 2012/06/18 13:56:57 bcbrock Exp $ /// \file poremodel.C /// \brief The PORE hardware engine model and interface to the virtual @@ -37,6 +38,9 @@ using namespace vsbe; /////////////// Common Creation/Control Interface //////////////////// +/// \bug The underlying PORE model does not model reset correctly. This is +/// fixed here. + int PoreModel::restart() { @@ -44,6 +48,60 @@ PoreModel::restart() iv_modelError = ME_SUCCESS; iv_instructions = 0; iv_stopCode = 0; + + // Begin bug workaround + + registerWriteRaw(PORE_STATUS, 0); + + if (iv_ibufId == PORE_SLW) { + registerWriteRaw(PORE_CONTROL,0x8005ffffffffffffull); + } else { + registerWriteRaw(PORE_CONTROL,0x8000ffffffffffffull); + } + + registerWriteRaw(PORE_RESET,0); + + registerWriteRaw(PORE_ERROR_MASK,0x00bff00000000000ull); + + registerWriteRaw(PORE_PRV_BASE_ADDR0,0); + registerWriteRaw(PORE_PRV_BASE_ADDR1,0); + registerWriteRaw(PORE_OCI_MEMORY_BASE_ADDR0,0); + registerWriteRaw(PORE_OCI_MEMORY_BASE_ADDR1,0); + + if (iv_ibufId == PORE_SBE) { + registerWriteRaw(PORE_TABLE_BASE_ADDR, 0x0000000100040020ull); + } else { + registerWriteRaw(PORE_TABLE_BASE_ADDR, 0); + } + + registerWriteRaw(PORE_EXE_TRIGGER,0); + registerWriteRaw(PORE_SCRATCH0,0); + registerWriteRaw(PORE_SCRATCH1,0); + registerWriteRaw(PORE_SCRATCH2,0); + registerWriteRaw(PORE_IBUF_01,0); + registerWriteRaw(PORE_IBUF_2,0); + registerWriteRaw(PORE_DBG0,0); + registerWriteRaw(PORE_DBG1,0); + registerWriteRaw(PORE_PC_STACK0,0); + registerWriteRaw(PORE_PC_STACK1,0); + registerWriteRaw(PORE_PC_STACK2,0); + + registerWriteRaw(PORE_ID_FLAGS, iv_ibufId); + + registerWriteRaw(PORE_DATA0,0); + registerWriteRaw(PORE_MEM_RELOC,0); + + registerWriteRaw(PORE_I2C_E0_PARAM,0x0000000f00000000ull); + + registerWriteRaw(PORE_I2C_E1_PARAM,0); + registerWriteRaw(PORE_I2C_E2_PARAM,0); + + // End bug workaround + + if (iv_ibufId == PORE_SBE) { + registerWrite(PORE_EXE_TRIGGER,0); + } + return getStatus(); } @@ -111,7 +169,8 @@ PoreModel::run(const uint64_t i_instructions, uint64_t& o_ran) } o_ran++; iv_instructions++; - if (getModelError() != 0) { + me = getModelError(); + if (me != 0) { break; } } @@ -348,6 +407,174 @@ PoreModel::getStopCode() } +// 'Ram' a load or store instruction without modifying the final state of the +// PORE. + +static ModelError +_ramLoadStore(PoreModel& io_pore, + uint32_t i_instruction, uint64_t i_immediate, + uint64_t& io_d0, uint64_t i_a0, uint8_t i_p0) +{ + ModelError me; + PoreState state; + uint64_t control; + bool stateExtracted; + + do { + + // Extract the state, then load up the caller's register state + + stateExtracted = false; + + me = io_pore.extractState(state); + if (me) break; + + stateExtracted = true; + + me = io_pore.registerWrite(PORE_SCRATCH1, io_d0); + if (me) break; + me = io_pore.registerWrite(PORE_OCI_MEMORY_BASE_ADDR0, i_a0); + if (me) break; + me = io_pore.registerWrite(PORE_PRV_BASE_ADDR0, i_p0); + if (me) break; + + + // Stop the engine (set control register bit 0) and ram the + // instruction by writing PORE_IBUF_01. The model executes the + // instruction immediately w/o the necessity of run()-ing it. + + me = io_pore.registerRead(PORE_CONTROL, control); + if (me) break; + me = io_pore.registerWrite(PORE_CONTROL, control | BE64_BIT(0)); + if (me) break; + + me = io_pore.registerWrite(PORE_IBUF_2, i_immediate << 32); + if (me) break; + me = io_pore.registerWrite(PORE_IBUF_01, + (((uint64_t)i_instruction) << 32) | + i_immediate >> 32); + if (me) break; + + + // Extract the return value of D0 + + me = io_pore.registerRead(PORE_SCRATCH1, io_d0); + if (me) break; + + } while (0); + + if (stateExtracted) { + me = io_pore.installState(state); + } + + return me; +} + + +ModelError +PoreModel::getmemInteger(const PoreAddress& i_address, + uint64_t& o_data, + const size_t i_size) +{ + PoreAddress address; + int byte; + ModelError me; + + union { + uint64_t u64; + uint32_t u32[2]; + uint16_t u16[4]; + uint8_t u8[8]; + } data; + + do { + + // Check the address legality and alignment vis-a-vis the size, and + // align the address to an 8-byte boundary. + + address = i_address; + + if (!(address.iv_memorySpace & 0x8000) || + ((address.iv_offset & (i_size - 1)) != 0)) { + me = ME_INVALID_ARGUMENT; + break; + } + + byte = address.iv_offset % 8; + address.iv_offset -= byte; + + + // Ram "LD D0, 0, A0", then pull out the requested bytes in host + // format. + + me = _ramLoadStore(*this, + 0x64800000, 0, + data.u64, (uint64_t)address, 0); + if (me) break; + +#ifndef _BIG_ENDIAN + byte = 7 - byte; +#endif + + switch (i_size) { + + case 1: o_data = data.u8[byte]; break; + case 2: o_data = data.u16[byte / 2]; break; + case 4: o_data = data.u32[byte / 4]; break; + case 8: o_data = data.u64; break; + default: me = ME_INVALID_ARGUMENT; + + } + + if (me) break; + + } while (0); + + return me; +} + + +ModelError +PoreModel::putmemInteger(const PoreAddress& i_address, + const uint64_t i_data, + const size_t i_size) +{ + PoreAddress address; + int byte; + uint64_t d0; + ModelError me; + + do { + + // Check the address and size for legality. + + address = i_address; + + if ((i_size != 8) || + !(address.iv_memorySpace & 0x8000) || + ((address.iv_offset & (i_size - 1)) != 0)) { + me = ME_INVALID_ARGUMENT; + break; + } + + byte = address.iv_offset % 8; + address.iv_offset -= byte; + + + // Ram "STD D0, 0, A0" + + d0 = i_data; + me = _ramLoadStore(*this, + 0x72800000, 0, + d0, (uint64_t)address, 0); + if (me) break; + + } while (0); + + return me; +} + + //////////////////// PoreInterface Methods ///////////////////////// // The interface methods are responsible for ensuring that any errors are diff --git a/src/usr/pore/poreve/model/poremodel.H b/src/usr/pore/poreve/model/poremodel.H index be2446c1f..46f02ffd6 100644 --- a/src/usr/pore/poreve/model/poremodel.H +++ b/src/usr/pore/poreve/model/poremodel.H @@ -1,29 +1,30 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/pore/poreve/model/poremodel.H $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2012 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/poreve/model/poremodel.H $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ #ifndef __VSBE_POREMODEL_H #define __VSBE_POREMODEL_H -// $Id: poremodel.H,v 1.23 2011/11/11 00:55:26 bcbrock Exp $ +// $Id: poremodel.H,v 1.25 2012/06/18 13:56:57 bcbrock Exp $ /// \file poremodel.H /// \brief The PORE hardware engine model @@ -92,22 +93,19 @@ public: static PoreModel* create(PoreIbufId i_id, PoreInterface *i_interface); - /// Restart the PORE engine to its scan-flush state + /// Restart the PORE engine in its auto-POR or scan-flush state /// - /// For PORE-SBE, the engine is reset to begin execution from the OTPROM - /// at the proper location, with all configuration registers (e.g., the - /// I2C configuration) flushed to the correct state to begin an IPL. - /// - /// For the other engines, they are reset as documented and will not run - /// (correctly) until the BASE address and EXE trigger registers are - /// written. As a side effect the status of the PoreModel is computed and - /// returned. The PoreModel is defined to be in the restart (scan-flush) - /// state at the end of constructing the model. + /// For PORE-SBE, the engine is reset and inintialized as if the auto-POR + /// sequence had run. This means that the engine will be running at the + /// first program vector in the OTPROM. For the other engines, they are + /// reset as documented and will not run (correctly) until the BASE + /// address and EXE trigger registers are written. As a side effect the + /// status of the PoreModel is computed and returned. The application + /// should always restart() the model after construction to ensure that + /// the model is in the correct reset state. /// /// \retval status PORE-SBE returns 0 (running); The other engines return /// PORE_STATUS_HARDWARE_STOP. - /// - /// \bug Check to make sure this is true for the SBE. virtual int restart(); @@ -308,6 +306,62 @@ public: virtual int getStopCode(); + /// Read an integer from memory as seen by the PORE engine + /// + /// \param[in] i_address The PoreAddress of the memory to read, which must + /// be aligned to \a i_size. + /// + /// \param[out] o_data The data at \a i_address, as a right-justified \a + /// i_size byte unsigned integer in host endian format + /// + /// \param[in] i_size The data size in bytes, which must be either 1, 2, 4 + /// or 8. + /// + /// This method performs a memory read operation on the memory space as + /// seen by the PORE engine, interpreting the memory data as an \a i-size + /// byte integer. The \a i_address must specify an OCI (GPEn/SLW) or + /// I2C/PNOR (SBE) address (bit 0 of the address must be a 1). In + /// OCI-attached engines the address will be issued on the OCI. For SBE, + /// the address is issued to the addressed I2C controller (or the + /// psuedo-I2C controller that provides access to the PNOR). + /// + /// \note Use the getscom() method to read from PIB memory spaces. + /// + /// \returns Either 0 for success, or a ModelError return code in the + /// event of a failure. + virtual ModelError + getmemInteger(const PoreAddress& i_address, + uint64_t& o_data, + const size_t i_size); + + /// Write an integer to memory as seen from the PORE engine + /// + /// \param[in] i_address The PoreAddress of the memory to write, which + /// must be aligned to \a i_size + /// + /// \param[in] i_data The data to write to \a i_address, as a + /// right-justified \a i_size byte unsigned integer in host endian format + /// + /// \param[in] i_size The data size in bytes. The method currently only + /// supports 8-byte writes. + /// + /// This method performs a memory write operation on the memory space as + /// seen by the PORE engine, performing endian-conversion of \a i_data if + /// necessary. The \a i_address must specify an OCI (GPEn/SLW) or + /// I2C/PNOR (SBE) address (bit 0 of the address must be a 1). In + /// OCI-attached engines the address will be issued on the OCI. For SBE, + /// the address is issued to the addressed I2C controller (or the + /// psuedo-I2C controller that provides access to the PNOR). + /// + /// \note Use the putscom() method to write to PIB memory spaces. + /// + /// \returns Either 0 for success, or a ModelError return code in the + /// event of a failure. + virtual ModelError + putmemInteger(const PoreAddress& i_address, + const uint64_t i_data, + const size_t i_size); + ///////////////////////// Abstract Interface ///////////////////////// diff --git a/src/usr/pore/poreve/model/poreregister.H b/src/usr/pore/poreve/model/poreregister.H index 24147365f..21aa32985 100644 --- a/src/usr/pore/poreve/model/poreregister.H +++ b/src/usr/pore/poreve/model/poreregister.H @@ -1,32 +1,35 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/pore/poreve/model/poreregister.H $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2012 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/poreve/model/poreregister.H $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ #ifndef __VSBE_POREREGISTER_H #define __VSBE_POREREGISTER_H -// $Id: poreregister.H,v 1.2 2011/08/03 17:59:00 bcbrock Exp $ +// $Id: poreregister.H,v 1.3 2012/06/15 12:34:39 bcbrock Exp $ /// \file poreregister.H /// \brief The PoreRegister and PoreRegisterWritable classes +/// +/// This header also includes selected register layout definitions #include <stdint.h> @@ -272,4 +275,45 @@ private: PoreDataBuffer& operator=(PoreDataBuffer& i_rhs); }; + +/// \bug These register layouts are defined in pore_model/ibuf/pore_regs.h, +/// however that header also includes a definition of a PoreAddress type that +/// conflicts with the type we define in PoreAddress.H. If the conflict can +/// be removed from pore_regs.h then we can #include that file instead of +/// duplicating it here. + +#include <endian.h> + +typedef union { + struct { +#if (__BYTE_ORDER == __BIG_ENDIAN) + uint64_t i2c_engine_identifier : 4; + uint64_t reserved0 : 1; + uint64_t i2c_engine_address_range : 3; + uint64_t reserved1 : 3; + uint64_t i2c_engine_port : 5; + uint64_t reserved2 : 1; + uint64_t i2c_engine_device_id : 7; + uint64_t reserved3 : 2; + uint64_t i2c_engine_speed : 2; + uint64_t i2c_done_max_polls : 4; /* I2C_E0_PARAM only */ + uint64_t reserved4 : 32; +#else + uint64_t reserved4 : 32; + uint64_t i2c_done_max_polls : 4; /* I2C_E0_PARAM only */ + uint64_t i2c_engine_speed : 2; + uint64_t reserved3 : 2; + uint64_t i2c_engine_device_id : 7; + uint64_t reserved2 : 1; + uint64_t i2c_engine_port : 5; + uint64_t reserved1 : 3; + uint64_t i2c_engine_address_range : 3; + uint64_t reserved0 : 1; + uint64_t i2c_engine_identifier : 4; +#endif + }; + uint64_t val; +} pore_i2c_en_param_reg; + + #endif // __VSBE_POREREGISTER_H diff --git a/src/usr/pore/poreve/pore_model/ibuf/pore_ibuf.h b/src/usr/pore/poreve/pore_model/ibuf/pore_ibuf.h index 33f9bc30f..5f19a0b47 100644 --- a/src/usr/pore/poreve/pore_model/ibuf/pore_ibuf.h +++ b/src/usr/pore/poreve/pore_model/ibuf/pore_ibuf.h @@ -1,25 +1,26 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/pore/poreve/pore_model/ibuf/pore_ibuf.h $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2012 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/poreve/pore_model/ibuf/pore_ibuf.h $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ #ifndef __PORE_IBUF_H__ #define __PORE_IBUF_H__ @@ -130,8 +131,10 @@ struct pore_model { pore_i2c_en_param_reg i2c_e_param[3]; /* 0x000000b8 * * 0x000000c0 * * 0x000000c8 */ - uint64_t branchTaken; /* last ins branch? pc updated? d0 */ - uint64_t broken; /* in case we ran on a breakpoint d8 */ + uint32_t branchTaken; /* last ins branch? pc updated? d0 */ + uint32_t broken; /* in case we ran on a breakpoint */ + uint32_t pore_interrupt_request; /* 0x000000d8 */ + uint32_t reserved; uint32_t oci_fetchBufferValid; /* 0x000000e0 */ uint32_t oci_fetchBufferCursor; uint64_t oci_fetchBuffer; /* 0x000000e8 */ diff --git a/src/usr/pore/poreve/pore_model/ibuf/pore_inline_decode.c b/src/usr/pore/poreve/pore_model/ibuf/pore_inline_decode.c index d2574fa80..bc8d28c90 100644 --- a/src/usr/pore/poreve/pore_model/ibuf/pore_inline_decode.c +++ b/src/usr/pore/poreve/pore_model/ibuf/pore_inline_decode.c @@ -1,25 +1,26 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/pore/poreve/pore_model/ibuf/pore_inline_decode.c $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2012 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/poreve/pore_model/ibuf/pore_inline_decode.c $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ #include <stdint.h> #include "pore_inline_decode.h" @@ -63,7 +64,7 @@ /// in which case any fields of \a dis not explicitly set will be undefined. void -pore_inline_decode_instruction(PoreInlineDecode *dis, uint32_t instruction) +vpore_inline_decode_instruction(PoreInlineDecode *dis, uint32_t instruction) { dis->instruction = instruction; @@ -120,7 +121,7 @@ pore_inline_decode_instruction(PoreInlineDecode *dis, uint32_t instruction) /// in which case any fields of \a dis not explicitly set will be undefined. void -pore_inline_decode_imd64(PoreInlineDecode *dis, uint64_t imd64) +vpore_inline_decode_imd64(PoreInlineDecode *dis, uint64_t imd64) { dis->imd64 = imd64; dis->impc48 = dis->imd64 & 0xffffffffffffull; diff --git a/src/usr/pore/poreve/pore_model/ibuf/pore_inline_decode.h b/src/usr/pore/poreve/pore_model/ibuf/pore_inline_decode.h index d34317903..604f32d7e 100644 --- a/src/usr/pore/poreve/pore_model/ibuf/pore_inline_decode.h +++ b/src/usr/pore/poreve/pore_model/ibuf/pore_inline_decode.h @@ -1,25 +1,26 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/pore/poreve/pore_model/ibuf/pore_inline_decode.h $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2012 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/poreve/pore_model/ibuf/pore_inline_decode.h $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ #ifndef __PORE_INLINE_DECODE_H__ #define __PORE_INLINE_DECODE_H__ @@ -193,10 +194,10 @@ typedef struct { } PoreInlineDecode; void -pore_inline_decode_instruction(PoreInlineDecode *dis, uint32_t instruction); +vpore_inline_decode_instruction(PoreInlineDecode *dis, uint32_t instruction); void -pore_inline_decode_imd64(PoreInlineDecode *dis, uint64_t imd64); +vpore_inline_decode_imd64(PoreInlineDecode *dis, uint64_t imd64); #ifdef __cplusplus } /* closing brace for extern "C" */ diff --git a/src/usr/pore/poreve/pore_model/ibuf/pore_model.c b/src/usr/pore/poreve/pore_model/ibuf/pore_model.c index f5306fdb5..849155169 100644 --- a/src/usr/pore/poreve/pore_model/ibuf/pore_model.c +++ b/src/usr/pore/poreve/pore_model/ibuf/pore_model.c @@ -1,25 +1,26 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/pore/poreve/pore_model/ibuf/pore_model.c $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2012 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/poreve/pore_model/ibuf/pore_model.c $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ /****************************************************************************** * * Virtual PORe Engine @@ -39,6 +40,7 @@ static int fetch(pore_model_t p); static int decode(pore_model_t p); static int execute(pore_model_t p); static int finishBrokenInstruction(pore_model_t p); +static int __pore_flush_reset(pore_model_t p); #define PORE_GET_BITS(X,S,N) \ ((((~(0xFFFFFFFFFFFFFFFFull >> (N))) >> (S)) \ @@ -283,31 +285,49 @@ pore_control_reg_write(pore_model_t p, uint64_t val, uint64_t mask) static inline int pore_exe_trigger_reg_write(pore_model_t p, uint64_t val, uint64_t mask) { - int me = PORE_SUCCESS; - val &= PORE_EXE_TRIGGER_VALID_BITS; if (p->reset.fn_reset == 1) { - me = PORE_ERR_IN_RESET; + return PORE_ERR_IN_RESET; - } else if (mask == PORE_BITS_32_63) { - p->exe_trigger.val = ((val & mask) | - (p->exe_trigger.val & ~mask)); + } - } else if (p->control.lock_exe_trig) { - me = PORE_ERR_REGISTER_LOCKED; + if (p->control.lock_exe_trig && + !p->control.interrupt_sequencer_enabled) { + return PORE_ERR_REGISTER_LOCKED; + } - } else { + if (mask == PORE_BITS_32_63) { p->exe_trigger.val = ((val & mask) | (p->exe_trigger.val & ~mask)); + return PORE_SUCCESS; + } - // Lock the EXE_TRIGGER register, compute the - // new starting PC, and begin execution. + if (p->control.interrupt_sequencer_enabled) { + if (p->control.pore_interruptible == 0) { + /* enque request, remember desired exe_trigger_reg */ + p->pore_interrupt_request = 1; + p->dbg0.interrupt_counter = 0x00; + p->exe_trigger.val = ((val & mask) | + (p->exe_trigger.val & ~mask)); - p->control.lock_exe_trig = 1; - p->control.start_stop = 0; - pore_exeVector(p, p->exe_trigger.start_vector); + return PORE_SUCCESS; + } else { + /* else do the trigger, and wipe out the request */ + p->pore_interrupt_request = 0; + } } - return me; + + p->exe_trigger.val = ((val & mask) | + (p->exe_trigger.val & ~mask)); + + /* Lock the EXE_TRIGGER register, compute the new starting PC, + * and begin execution. + */ + p->control.lock_exe_trig = 1; + p->control.start_stop = 0; + pore_exeVector(p, p->exe_trigger.start_vector); + + return PORE_SUCCESS; } /// write method for IBUF_01 register. Upon write to the ibuf_0 part @@ -339,6 +359,21 @@ pore_ibuf_01_reg_write(pore_model_t p, uint64_t val, uint64_t mask) if (me != PORE_SUCCESS) return me; + /* Extension for interruptible operation of SLW instance */ + if (p->control.interrupt_sequencer_enabled && + p->pore_interrupt_request) { + + if (p->control.pore_interruptible) { + __pore_flush_reset(p); + pore_exe_trigger_reg_write(p, + p->exe_trigger.val, + PORE_BITS_0_63); + } else { + if (p->dbg0.interrupt_counter != 0xff) + p->dbg0.interrupt_counter++; + } + } + /* FIXME In case of stuffing instructions I strongly assume that the PC must not be upated. */ } @@ -601,7 +636,9 @@ static int __writeReg(pore_model_t p, pore_internal_reg_t reg, uint64_t val) break; case PORE_TABLE_BASE_ADDR_ENC: - p->table_base_addr.val = val; break; + p->table_base_addr.val = val; + break; + case PORE_EXE_TRIGGER_ENC: /** * A COPY instruction to the EXE_Trigger register will @@ -786,7 +823,7 @@ static void signalFatalError(pore_model_t p) * * Each error cause is indicated by a corresponding bit in DBG * Register1. Since errors on this event are fatal for PORE, it is - * highly recommended to configure the actions ďż˝Stop IBUF execution + * highly recommended to configure the actions âStop IBUF execution * and IBUF fatal error in the IBUF Error Mask register. This is * the default setting. * @@ -1414,9 +1451,9 @@ static int decode(pore_model_t p) return PORE_ERR_INVALID_PARAM; dis = &p->dis; - pore_inline_decode_instruction(dis, p->ibuf_01.ibuf0); - pore_inline_decode_imd64(dis, ((uint64_t)p->ibuf_01.ibuf1 << 32 | - (uint64_t)p->ibuf_2.ibuf2)); + vpore_inline_decode_instruction(dis, p->ibuf_01.ibuf0); + vpore_inline_decode_imd64(dis, ((uint64_t)p->ibuf_01.ibuf1 << 32 | + (uint64_t)p->ibuf_2.ibuf2)); p->opcode_len = 4; if (dis->long_instruction) @@ -1723,7 +1760,6 @@ static const uint16_t bin_2_unary[] = { }; static int pore_scand_read(pore_model_t p, PoreAddress *addr, uint32_t *word) - { int rc; uint64_t data; @@ -2594,6 +2630,20 @@ int pore_step(pore_model_t p) return rc; } + /* Extension for interruptible operation of SLW instance */ + if (p->control.interrupt_sequencer_enabled && + p->pore_interrupt_request) { + + if (p->control.pore_interruptible) { + __pore_flush_reset(p); + pore_exe_trigger_reg_write(p, p->exe_trigger.val, + PORE_BITS_0_63); + } else { + if (p->dbg0.interrupt_counter != 0xff) + p->dbg0.interrupt_counter++; + } + } + return rc; } @@ -2621,10 +2671,9 @@ void pore_dump(pore_model_t p) " IBUF: %08llx %08x.%08x.%08x\n" "-------------------------------------" "-------------------------------------\n" - " D0 : %016llx D1 : %016llx\n" - " A0 : %04x:%08x A1 : %04x:%08x\n" - " P0 : %02x P1 : %02x\n" - " CTR : %06x\n" + " D0: %016llx D1: %016llx\n" + " A0: %04x:%08x A1: %04x:%08x\n" + " P0: %02x P1: %02x CTR: %06x\n" "-------------------------------------" "-------------------------------------\n", __func__, @@ -2684,6 +2733,11 @@ void pore_dump(pore_model_t p) " DATA0: %016llx MEM_RELOC: %016llx\n" " I2C_E0: %016llx I2C_E1: %016llx\n" " I2C_E2: %016llx PC: %016llx\n" + " Internal State\n" + " branchTaken/broken: %lld/%lld\n" + " pore_interrupt_request: %lld\n" + " oci_fetchBufValid/Cursor: %lld/%lld\n" + " oci_fetchBuf: %016llx\n" "-------------------------------------" "-------------------------------------\n", (long long)p->status.val, (long long)p->control.val, @@ -2702,62 +2756,91 @@ void pore_dump(pore_model_t p) (long long)p->i2c_e_param[0].val, (long long)p->i2c_e_param[1].val, (long long)p->i2c_e_param[2].val, - (long long)p->status.pc); + (long long)p->status.pc, + (long long)p->branchTaken, (long long)p->broken, + (long long)p->pore_interrupt_request, + (long long)p->oci_fetchBufferValid, + (long long)p->oci_fetchBufferCursor, + (long long)p->oci_fetchBuffer); } -/* Model Creation ************************************************************/ +/* Model Creation and Reset **************************************************/ -int pore_flush_reset(pore_model_t p) +static int __pore_flush_reset(pore_model_t p) { - dprintf(p, "%s: %s\n", __func__, p->name); - + /* --------------- always ------------------------------------------ */ + /* STATUS */ p->status.val = 0; p->status.cur_state = PORE_STATE_WAIT; - - p->control.val = 0; - p->control.start_stop = 1; - - p->control.lock_exe_trig = 0; - p->control.check_parity = 0; - p->control.prv_parity = 0; - p->control.pc_brk_pt = 0xffffffffffffull; + p->status.pc = 0; p->prv_base[0].val = 0; p->prv_base[1].val = 0; p->oci_base[0].val = 0; p->oci_base[1].val = 0; - p->table_base_addr.val = 0; - p->exe_trigger.val = 0; + + /* SCR0, SRC1, IBUF01, IBUF2 */ p->scratch0.val = 0; p->scratch1 = 0; p->scratch2 = 0; p->ibuf_01.val = 0; p->ibuf_2.val = 0; + /* ID_FLAGS, DBG0, DBG1, PC_STACK0/1/2, DATA0 */ p->id_flags.val = p->id_flags.ibuf_id; /* keep ibuf_id */ p->dbg0.val = 0; p->dbg1.val = 0; p->pc_stack[0].val = 0; /* clears one bits on a write */ p->pc_stack[1].val = 0; p->pc_stack[2].val = 0; - p->data0 = 0; - p->memory_reloc.val = 0; - p->status.pc = 0; + + /* Internal model state */ p->err_code = 0; p->branchTaken = 0; p->broken = 0; p->singleStep = 0; p->forcedBranchMode = FORCED_BRANCH_DISALLOWED; p->forcedPc = 0; - /* page 74: IBUF Err Mask, not altered during functional PORE reset. */ + /* Externally attached busses */ poreb_reset(p->pib); /* reset bus models, e.g. clear buffers */ poreb_reset(p->mem); return 0; } +int pore_flush_reset(pore_model_t p) +{ + dprintf(p, "%s: %s\n", __func__, p->name); + + /* --------------- exclude those regs for interruptible PORE case -- */ + /* EXE_TRIGGER */ + p->exe_trigger.val = 0; + + /* CONTROL */ + p->control.val = 0; + p->control.start_stop = 1; + p->control.lock_exe_trig = 0; + p->control.check_parity = 0; + p->control.prv_parity = 0; + p->control.pc_brk_pt = 0xffffffffffffull; + + /* TABLE_BASE */ + p->table_base_addr.val = 0; + + /* ERROR_MASK ... only at 1st init */ + /* page 74: IBUF Err Mask, not altered during functional PORE reset. */ + + /* MEMORY_RELOC */ + p->memory_reloc.val = 0; + + /* I2C_PARAM0/1/2 ... only at 1st init */ + + __pore_flush_reset(p); + return 0; +} + pore_model_t pore_model_create(const char *name) { pore_model_t p; @@ -2769,7 +2852,6 @@ pore_model_t pore_model_create(const char *name) p->name = name; pore_flush_reset(p); - p->status.pc = 0; p->enableHookInstruction = 0; p->enableAddressHooks = 0; @@ -3011,36 +3093,23 @@ pore_sbe_create(pore_bus_t pib) p->id_flags.ibuf_id = PORE_IBUF_ID_SBE; p->error_mask.val = 0x00BFF00000000000ull; /* FIXME spec undefined */ + p->control.interrupt_sequencer_enabled = 0; + p->control.pore_interruptible = 0; + /* SEEPROM */ - p->i2c_e_param[0].i2c_engine_identifier = 0xc; - p->i2c_e_param[0].i2c_engine_address_range = 0x2; - p->i2c_e_param[0].i2c_engine_port = 0x0; - p->i2c_e_param[0].i2c_engine_device_id = 0x0; - - /* OTPROM */ - p->i2c_e_param[1].i2c_engine_identifier = 0x1; - p->i2c_e_param[1].i2c_engine_address_range = 0x2; - p->i2c_e_param[1].i2c_engine_port = 0x0; - p->i2c_e_param[1].i2c_engine_device_id = 0x0; - - /* PNOR */ - p->i2c_e_param[2].i2c_engine_identifier = 0xb; - p->i2c_e_param[2].i2c_engine_address_range = 0x4; - p->i2c_e_param[2].i2c_engine_port = 0x0; - p->i2c_e_param[2].i2c_engine_device_id = 0x0; + p->i2c_e_param[0].i2c_engine_speed = 0x0f; /* OCI/MEM Route */ p->oci_base[0].val = 0; - p->oci_base[0].oci_mem_route = 0xa; /* matches here SEEPROM */ - p->oci_base[0].oci_base_address = 0x000000000; - p->oci_base[1].val = 0; - p->oci_base[1].oci_mem_route = 0x1; /* matches here OTP */ - p->oci_base[1].oci_base_address = 0x000000000; + /* The 0x00040000 in the SBE address space translates to the + * 0x00008000 (>>3) on the PIB bus. + */ /* Table base address defines where start and exception vectors are */ p->table_base_addr.val = 0; - p->table_base_addr.table_base_address = 0x00010008 << 3; /* for SBE */ + p->table_base_addr.memory_space = 0x00001; /* for SBE */ + p->table_base_addr.table_base_address = 0x00040020; /* for SBE */ /* setup reference for the case it is not yet done. */ if (pib) @@ -3083,6 +3152,9 @@ __slw_create(const char *name, pore_bus_t pib, pore_bus_t oci, p->id_flags.ibuf_id = ibuf_id; p->error_mask.val = 0x00BFF00000000000ull; + p->table_base_addr.memory_space = 0x00000; /* for SLW/GPE */ + p->table_base_addr.table_base_address = 0x00000000; /* for SLW/GPE */ + /* setup reference for the case it is not yet done. */ if (pib) pib->pore = p; @@ -3114,7 +3186,12 @@ __slw_create(const char *name, pore_bus_t pib, pore_bus_t oci, pore_model_t pore_slw_create(pore_bus_t pib, pore_bus_t oci) { - return __slw_create("SLW", pib, oci, PORE_IBUF_ID_SLW); + pore_model_t pore; + + pore = __slw_create("SLW", pib, oci, PORE_IBUF_ID_SLW); + pore->control.interrupt_sequencer_enabled = 1; + pore->control.pore_interruptible = 1; + return pore; } pore_model_t diff --git a/src/usr/pore/poreve/pore_model/ibuf/pore_regs.h b/src/usr/pore/poreve/pore_model/ibuf/pore_regs.h index 0376deeff..8caa50c1a 100644 --- a/src/usr/pore/poreve/pore_model/ibuf/pore_regs.h +++ b/src/usr/pore/poreve/pore_model/ibuf/pore_regs.h @@ -1,25 +1,26 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/pore/poreve/pore_model/ibuf/pore_regs.h $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2012 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/poreve/pore_model/ibuf/pore_regs.h $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ #ifndef __PORE_REGS__ #define __PORE_REGS__ @@ -77,11 +78,18 @@ typedef union { uint64_t prv_parity : 1; uint64_t trap_enable : 1; /* bits 12:15 */ - uint64_t tbd : 4; + uint64_t narrow_mode_trace : 1; + uint64_t pore_interruptible : 1; + uint64_t pore_done_override : 1; + uint64_t interrupt_sequencer_enabled : 1; + /* bits 16:63 */ uint64_t pc_brk_pt : 48; #else uint64_t pc_brk_pt : 48; - uint64_t tbd : 4; + uint64_t interrupt_sequencer_enabled : 1; + uint64_t pore_done_override : 1; + uint64_t pore_interruptible : 1; + uint64_t narrow_mode_trace : 1; uint64_t trap_enable : 1; uint64_t prv_parity : 1; uint64_t check_parity : 1; @@ -303,19 +311,29 @@ typedef union { uint64_t val; } pore_ibuf_2_reg; -#define PORE_DBG0_VALID_BITS 0xfffffffff0000000ull +#define PORE_DBG0_VALID_BITS 0xffffffffffff0000ull typedef union { struct { #if (__BYTE_ORDER == __BIG_ENDIAN) uint64_t last_completed_address : 32; - uint64_t filler_bit : 1; /* clearOnAnyWrite */ - uint64_t last_ret_code_prv : 3; /* clearOnAnyWrite */ - uint64_t spare : 28; /* clearOnAnyWrite */ + uint64_t last_acc_parity_fail_ind : 1; /* clearOnAnyWrite */ + uint64_t last_ret_code_prv : 3; /* clearOnAnyWrite */ + uint64_t i2c_bad_status_0 : 1; /* clearOnAnyWrite */ + uint64_t i2c_bad_status_1 : 1; /* clearOnAnyWrite */ + uint64_t i2c_bad_status_2 : 1; /* clearOnAnyWrite */ + uint64_t i2c_bad_status_3 : 1; /* clearOnAnyWrite */ + uint64_t interrupt_counter : 8; /* ROX */ + uint64_t spare : 16; /* clearOnAnyWrite */ #else - uint64_t spare : 28; /* clearOnAnyWrite */ - uint64_t last_ret_code_prv : 3; /* clearOnAnyWrite */ - uint64_t filler_bit : 1; /* clearOnAnyWrite */ + uint64_t spare : 16; + uint64_t interrupt_counter : 8; /* ROX */ + uint64_t i2c_bad_status_3 : 1; /* clearOnAnyWrite */ + uint64_t i2c_bad_status_2 : 1; /* clearOnAnyWrite */ + uint64_t i2c_bad_status_1 : 1; /* clearOnAnyWrite */ + uint64_t i2c_bad_status_0 : 1; /* clearOnAnyWrite */ + uint64_t last_ret_code_prv : 3; + uint64_t last_acc_parity_fail_ind : 1; uint64_t last_completed_address : 32; #endif }; @@ -528,8 +546,10 @@ typedef union { ((bits) & 0x3f)) #ifndef FASTI2C_BASE_OFFSET -# define FASTI2C_BASE_OFFSET 0x00008000 +/* # define FASTI2C_BASE_OFFSET 0x00008000 */ +# define FASTI2C_BASE_OFFSET 0x00000000 /* new default */ #endif + #define FASTI2C_CONTROL_OFFSET (FASTI2C_BASE_OFFSET + 0x00000000) #define FASTI2C_RESET_OFFSET (FASTI2C_BASE_OFFSET + 0x00000001) #define FASTI2C_STATUS_OFFSET (FASTI2C_BASE_OFFSET + 0x00000002) diff --git a/src/usr/pore/poreve/pore_model/include/pore_model.h b/src/usr/pore/poreve/pore_model/include/pore_model.h index b7f3bb5a4..90ee2247c 100644 --- a/src/usr/pore/poreve/pore_model/include/pore_model.h +++ b/src/usr/pore/poreve/pore_model/include/pore_model.h @@ -1,25 +1,26 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/pore/poreve/pore_model/include/pore_model.h $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2012 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/poreve/pore_model/include/pore_model.h $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ #ifndef __PORE_MODEL__ #define __PORE_MODEL__ @@ -50,7 +51,7 @@ extern "C" { #endif /** Version of the vPORe model */ -#define PORE_MODEL_VERSION 0x0001000C +#define PORE_MODEL_VERSION 0x0001000E /** * Different PORe incarations diff --git a/src/usr/pore/poreve/pore_model/include/pore_wrap.h b/src/usr/pore/poreve/pore_model/include/pore_wrap.h index 370ea378e..e4f5f897f 100644 --- a/src/usr/pore/poreve/pore_model/include/pore_wrap.h +++ b/src/usr/pore/poreve/pore_model/include/pore_wrap.h @@ -1,25 +1,26 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/pore/pore_model/include/pore_wrap.h $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2011 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/poreve/pore_model/include/pore_wrap.h $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2011-2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ #ifndef __PORE_TRACE_H__ #define __PORE_TRACE_H__ @@ -40,6 +41,7 @@ #include <stdio.h> #include <stdarg.h> #include <trace/interface.H> +#include <endian.h> #ifdef __cplusplus extern "C" { diff --git a/src/usr/pore/poreve/porevesrc/bus.C b/src/usr/pore/poreve/porevesrc/bus.C index fdf3e90a5..beabe7241 100644 --- a/src/usr/pore/poreve/porevesrc/bus.C +++ b/src/usr/pore/poreve/porevesrc/bus.C @@ -1,26 +1,27 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/pore/poreve/porevesrc/bus.C $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2012 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END -// $Id: bus.C,v 1.22 2012/01/05 23:15:54 bcbrock Exp $ +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/poreve/porevesrc/bus.C $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ +// $Id: bus.C,v 1.25 2012/03/20 22:52:49 bcbrock Exp $ /// \file bus.C /// \brief PoreVe bus and base device models @@ -35,7 +36,7 @@ using namespace vsbe; //----------------------------------------------------------------------------- Bus::Bus() : - iv_primarySlaves(NULL), + iv_primarySlaves(NULL), iv_secondarySlaves(NULL) { } @@ -52,7 +53,9 @@ Bus::attachPrimarySlave(Slave* i_slave) if( iv_primarySlaves == 0 ) { i_slave->iv_next = 0; - }else{ + } + else + { i_slave->iv_next = iv_primarySlaves; } iv_primarySlaves = i_slave; @@ -65,7 +68,9 @@ Bus::attachSecondarySlave(Slave* i_slave) if( iv_secondarySlaves == 0 ) { i_slave->iv_next = 0; - }else{ + } + else + { i_slave->iv_next = iv_secondarySlaves; } iv_secondarySlaves = i_slave; @@ -83,46 +88,49 @@ Bus::operation(Transaction& trans) { for( slave = iv_primarySlaves; slave; slave = slave->iv_next ) { - if( (trans.iv_address >= slave->iv_base) && (trans.iv_address < (slave->iv_base + slave->iv_size) ) ) + if( (trans.iv_address >= slave->iv_base) && + (trans.iv_address < (slave->iv_base + slave->iv_size) ) ) { - break; // found a primary slave + break; // found a primary slave } } if( slave == 0 ) - { // primary slaves did not hold the transaction address. Try using the secondary slaves. - for( slave = iv_secondarySlaves; slave; slave = slave->iv_next ) - { - if( (trans.iv_address >= slave->iv_base) && (trans.iv_address < (slave->iv_base + slave->iv_size) ) ) - { - break; // found a secondary slave - } - } + { // primary slaves did not hold the transaction address. + // Try using the secondary slaves. + for( slave = iv_secondarySlaves; slave; slave = slave->iv_next ) + { + if( (trans.iv_address >= slave->iv_base) && + (trans.iv_address < (slave->iv_base + slave->iv_size) ) ) + { + break; // found a secondary slave + } + } } break; - - }while(0); + } while(0); do { - if( slave == 0 ) // neither primary nor secondary slaves held the address + if( slave == 0 ) // neither primary nor secondary slaves held the addr { - trans.busError(ME_NOT_MAPPED_ON_BUS); - rc= 1; - break; + trans.busError(ME_NOT_MAPPED_ON_BUS); + FAPI_SET_HWP_ERROR(rc, RC_POREVE_BUS_ME_NOT_MAPPED_IN_BUS); + break; } - if( (trans.iv_mode & slave->iv_permissions) == 0 ){ - trans.busError(ME_BUS_SLAVE_PERMISSION_DENIED); - rc= 1; - break; - } + if( (trans.iv_mode & slave->iv_permissions) == 0 ) + { + trans.busError(ME_BUS_SLAVE_PERMISSION_DENIED); + FAPI_SET_HWP_ERROR(rc, RC_POREVE_BUS_ME_NOT_MAPPED_IN_BUS); + break; + } trans.iv_offset = trans.iv_address - slave->iv_base; rc = slave->operation( trans ); break; - }while(1); + } while(0); return rc; } @@ -132,7 +140,6 @@ Slave::Slave() :iv_base(0), iv_size(0), iv_permissions(0), iv_next(NULL), iv_target(NULL), iv_dataBuffer(NULL) { - } //----------------------------------------------------------------------------- @@ -157,7 +164,7 @@ PibSlave::operation(Transaction& io_transaction) fapi::ReturnCode rc; PibTransaction* pt = (PibTransaction*)&io_transaction; - if( io_transaction.iv_mode & ACCESS_MODE_READ ) + if( io_transaction.iv_mode & (ACCESS_MODE_READ | ACCESS_MODE_EXECUTE)) { rc = getScom( io_transaction.iv_address, io_transaction.iv_data ); } @@ -166,33 +173,41 @@ PibSlave::operation(Transaction& io_transaction) rc = putScom( io_transaction.iv_address, io_transaction.iv_data ); } - if( rc.ok() ) - { + if ( rc.ok() ) { pt->iv_pcbReturnCode = PCB_SUCCESS; - } - else - { - if( rc & fapi_PCB_RESOURCE_BUSY ){ + } else { + fapi::ReturnCode rc1; + if( rc == fapi_PCB_RESOURCE_BUSY ){ pt->iv_pcbReturnCode = PCB_RESOURCE_OCCUPIED; - }else if( rc & fapi_PCB_OFFLINE_ERROR ){ + rc = rc1; + }else if( rc == fapi_PCB_OFFLINE_ERROR ){ pt->iv_pcbReturnCode = PCB_CHIPLET_OFFLINE; - }else if( rc & fapi_PCB_PARTIAL_ERROR ){ + rc = rc1; + }else if( rc == fapi_PCB_PARTIAL_ERROR ){ pt->iv_pcbReturnCode = PCB_PARTIAL_GOOD; - }else if( rc & fapi_PCB_ADDRESS_ERROR ){ + rc = rc1; + }else if( rc == fapi_PCB_ADDRESS_ERROR ){ pt->iv_pcbReturnCode = PCB_ADDRESS_ERROR; - }else if( rc & fapi_PCB_CLOCK_ERROR ){ + rc = rc1; + }else if( rc == fapi_PCB_CLOCK_ERROR ){ pt->iv_pcbReturnCode = PCB_CLOCK_ERROR; - }else if( rc & fapi_PCB_PARITY_ERROR ){ + rc = rc1; + }else if( rc == fapi_PCB_PARITY_ERROR ){ pt->iv_pcbReturnCode = PCB_PACKET_ERROR; - }else if( rc & fapi_PCB_TIMEOUT_ERROR ){ + rc = rc1; + }else if( rc == fapi_PCB_TIMEOUT_ERROR ){ pt->iv_pcbReturnCode = PCB_TIMEOUT; + rc = rc1; }else{ pt->iv_pcbReturnCode = PCB_TIMEOUT; - } - rc = 0; + } } - io_transaction.iv_modelError = ME_SUCCESS; + if ( rc.ok() ) { + io_transaction.iv_modelError = ME_SUCCESS; + } else { + io_transaction.iv_modelError = ME_FAILURE; + } return rc; } @@ -212,7 +227,6 @@ Slave::configure( iv_base = i_base; iv_size = i_size; iv_permissions = i_permissions; - iv_next = NULL; } @@ -222,8 +236,9 @@ fapi::ReturnCode PibSlave::getScom(const uint32_t i_offset, uint64_t& o_data) { fapi::ReturnCode rc; - rc = fapiGetScom( *iv_target, i_offset, *iv_dataBuffer ); - o_data = iv_dataBuffer->getDoubleWord( 0 ); + ecmdDataBufferBase l_dataBuffer; + rc = fapiGetScom( *iv_target, i_offset, l_dataBuffer ); + o_data = l_dataBuffer.getDoubleWord( 0 ); return rc; } @@ -233,9 +248,10 @@ fapi::ReturnCode PibSlave::putScom(const uint32_t i_offset, const uint64_t i_data) { fapi::ReturnCode rc; - iv_dataBuffer->setDoubleWordLength( 1 ); - iv_dataBuffer->setDoubleWord( 0, i_data ); - rc = fapiPutScom( *iv_target, i_offset, *iv_dataBuffer ); + ecmdDataBufferBase l_dataBuffer(64); + + l_dataBuffer.setDoubleWord( 0, i_data ); + rc = fapiPutScom( *iv_target, i_offset, l_dataBuffer ); return rc; } @@ -243,7 +259,7 @@ PibSlave::putScom(const uint32_t i_offset, const uint64_t i_data) //----------------------------------------------------------------------------- PibMemory::PibMemory() : -iv_passThrough(false),iv_memory(NULL) + iv_passThrough(false), iv_memory(NULL) { } @@ -276,7 +292,6 @@ PibMemory::configure( iv_size = i_size; iv_permissions = i_permissions; iv_memory = i_memory; - iv_next = NULL; } @@ -288,9 +303,13 @@ PibMemory::operation(Transaction& io_transaction) fapi::ReturnCode rc; ModelError me; + FAPI_SET_HWP_ERROR(rc, RC_POREVE_PIBMEM_OPERATION_ERROR); + if( io_transaction.iv_mode & ACCESS_MODE_READ ) { - me = iv_memory->read( (uint32_t)(io_transaction.iv_offset * TRANSACTION_SIZE_IN_BYTES), io_transaction.iv_data, TRANSACTION_SIZE_IN_BYTES ); + me = iv_memory->read( + (uint32_t)(io_transaction.iv_offset * TRANSACTION_SIZE_IN_BYTES), + io_transaction.iv_data, TRANSACTION_SIZE_IN_BYTES ); if( me == ME_NOT_MAPPED_IN_MEMORY && iv_passThrough ) { rc = getScom( io_transaction.iv_address, io_transaction.iv_data ); @@ -306,7 +325,9 @@ PibMemory::operation(Transaction& io_transaction) } else if( io_transaction.iv_mode & ACCESS_MODE_WRITE ) { - me = iv_memory->write( (uint32_t)(io_transaction.iv_offset * TRANSACTION_SIZE_IN_BYTES), io_transaction.iv_data, TRANSACTION_SIZE_IN_BYTES ); + me = iv_memory->write( + (uint32_t)(io_transaction.iv_offset * TRANSACTION_SIZE_IN_BYTES), + io_transaction.iv_data, TRANSACTION_SIZE_IN_BYTES ); if( me == ME_NOT_MAPPED_IN_MEMORY && iv_passThrough ) { rc = putScom( io_transaction.iv_address, io_transaction.iv_data ); @@ -322,7 +343,9 @@ PibMemory::operation(Transaction& io_transaction) } else { - me = iv_memory->fetch( (uint32_t)(io_transaction.iv_offset * TRANSACTION_SIZE_IN_BYTES), io_transaction.iv_data, TRANSACTION_SIZE_IN_BYTES ); + me = iv_memory->fetch( + (uint32_t)(io_transaction.iv_offset * TRANSACTION_SIZE_IN_BYTES), + io_transaction.iv_data, TRANSACTION_SIZE_IN_BYTES ); if( me == ME_NOT_MAPPED_IN_MEMORY && iv_passThrough ) { rc = getScom( io_transaction.iv_address, io_transaction.iv_data ); @@ -339,13 +362,9 @@ PibMemory::operation(Transaction& io_transaction) io_transaction.busError( me ); - if( me == ME_SUCCESS ) - { - rc = (uint32_t)0; // if read/write or getScom/putScom succeeded then set rc = 0 - } - - // if read/write failed then rc == 1 by default - // if read/write returned ME_NOT_MAPPED_IN_MEMORY && pass through true then rc == value returned from putScom or getScom + // if read/write failed then rc == RC_PIBMEM_OPERATION_ERROR by default + // if read/write returned ME_NOT_MAPPED_IN_MEMORY && pass through true then + // rc == value returned from putScom or getScom return rc; } @@ -363,6 +382,17 @@ Memory::Memory() : //----------------------------------------------------------------------------- Memory::~Memory() { + MemoryImage* m1 = iv_images; + while (m1) + { + MemoryImage* m2 = m1->iv_next; + delete m1; + m1 = m2; + if (m2 == iv_images) + { + break; + } + } } //----------------------------------------------------------------------------- @@ -372,16 +402,20 @@ Memory::checkCrc() MemoryImage* mi = iv_images; bool rc = true; - do{ - - if( mi->checkCrc() == false ) - { + if (iv_images == 0) + { rc = false; - break; - } - mi = mi->iv_next; + } - }while( mi != iv_images ); + while (rc == true) + { + rc = mi->checkCrc(); + mi = mi->iv_next; + if (mi == iv_images) + { + break; + } + } return rc; } @@ -405,67 +439,74 @@ Memory::read( o_data = 0; // Assure all bytes are cleared me = ME_SUCCESS; - do{ - if( iv_images == 0 ) - { - me = ME_NOT_MAPPED_IN_MEMORY; - break; - } - mi = iv_images; - mi_found = 0; - do{ - - if( (i_offset >= mi->iv_base) && ((i_offset + i_size) <= (mi->iv_base + mi->iv_size) ) ) + do + { + if( iv_images == 0 ) { - mi_found= 1; - iv_images = mi; // have the Memory always point to the last MemoryImage that was used - break; // we found a chunk of memory containing the transaction address + me = ME_NOT_MAPPED_IN_MEMORY; + break; } - mi = mi->iv_next; + mi = iv_images; + mi_found = 0; + do + { + if( (i_offset >= mi->iv_base) && + ((i_offset + i_size) <= (mi->iv_base + mi->iv_size) ) ) + { + mi_found= 1; + iv_images = mi; // have the Memory always point to the last + // MemoryImage that was used + break; // we found a chunk of memory containing the + // transaction address + } + mi = mi->iv_next; - }while( mi != iv_images ); + } while( mi != iv_images ); - if( ! mi_found ) - { // There was no MemoryImage that contained the transaction address - me = ME_NOT_MAPPED_IN_MEMORY; - break; - } + if( ! mi_found ) + { // There was no MemoryImage that contained the transaction address + me = ME_NOT_MAPPED_IN_MEMORY; + break; + } - if( (mi->iv_permissions & ACCESS_MODE_READ ) == 0 ) - { // The permissions over the memory block do not allow the mode being used by the transaction - me = ME_MEMORY_IMAGE_PERMISSION_DENIED; - break; - } + if( (mi->iv_permissions & ACCESS_MODE_READ ) == 0 ) + { // The permissions over the memory block do not allow the mode + // being used by the transaction + me = ME_MEMORY_IMAGE_PERMISSION_DENIED; + break; + } - // Init the character pointer into the eprom image we are using. - from_ptr = (char*)mi->iv_image + (i_offset - mi->iv_base); + // Init the character pointer into the eprom image we are using. + from_ptr = (char*)mi->iv_image + (i_offset - mi->iv_base); - // Init the character pointer into the o_data buffer. - // Take care of Endianess by moving to one or the other end of the buffer as appropriate. + // Init the character pointer into the o_data buffer. + // Take care of Endianess by moving to one or the other end of the + // buffer as appropriate. #ifdef _BIG_ENDIAN to_ptr = (char*)&o_data + (TRANSACTION_SIZE_IN_BYTES - i_size); #else to_ptr = ((char*)&o_data + i_size -1); #endif - for( cnt = 0; cnt < i_size; cnt++ ) - { - *to_ptr = *from_ptr++; + for( cnt = 0; cnt < i_size; cnt++ ) + { + *to_ptr = *from_ptr++; - // Move the to pointer either forward or backward as appropriate for Endianess + // Move the to pointer either forward or backward as appropriate + // for Endianess #ifdef _BIG_ENDIAN - to_ptr++; + to_ptr++; #else - to_ptr--; + to_ptr--; #endif - } + } - me = ME_SUCCESS; - break; - }while(1); + me = ME_SUCCESS; + break; + } while(0); #if POREVE_STATISTICS - iv_reads++; + iv_reads++; #endif return me; @@ -489,67 +530,74 @@ Memory::fetch( o_data = 0; // Assure all bytes are cleared me = ME_SUCCESS; - do{ - if( iv_images == 0 ) - { - me = ME_NOT_MAPPED_IN_MEMORY; - break; - } - mi = iv_images; - mi_found = 0; - do{ - - if( (i_offset >= mi->iv_base) && ((i_offset + i_size) <= (mi->iv_base + mi->iv_size) ) ) + do + { + if( iv_images == 0 ) { - mi_found= 1; - iv_images = mi; // have the Memory always point to the last MemoryImage that was used - break; // we found a chunk of memory containing the transaction address + me = ME_NOT_MAPPED_IN_MEMORY; + break; } - mi = mi->iv_next; + mi = iv_images; + mi_found = 0; + do + { + if( (i_offset >= mi->iv_base) && + ((i_offset + i_size) <= (mi->iv_base + mi->iv_size) ) ) + { + mi_found= 1; + iv_images = mi; // have the Memory always point to the last + // MemoryImage that was used + break; // we found a chunk of memory containing the + // transaction address + } + mi = mi->iv_next; - }while( mi != iv_images ); + } while( mi != iv_images ); - if( ! mi_found ) - { // There was no MemoryImage that contained the transaction address - me = ME_NOT_MAPPED_IN_MEMORY; - break; - } + if( ! mi_found ) + { // There was no MemoryImage that contained the transaction address + me = ME_NOT_MAPPED_IN_MEMORY; + break; + } - if( (mi->iv_permissions & ACCESS_MODE_EXECUTE ) == 0 ) - { // The permissions over the memory block do not allow the mode being used by the transaction - me = ME_MEMORY_IMAGE_PERMISSION_DENIED; - break; - } + if( (mi->iv_permissions & ACCESS_MODE_EXECUTE ) == 0 ) + { // The permissions over the memory block do not allow the mode + // being used by the transaction + me = ME_MEMORY_IMAGE_PERMISSION_DENIED; + break; + } - // Init the character pointer into the eprom image we are using. - from_ptr = (char*)mi->iv_image + i_offset; + // Init the character pointer into the eprom image we are using. + from_ptr = (char*)mi->iv_image + i_offset; - // Init the character pointer into the o_data buffer. - // Take care of Endianess by moving to one or the other end of the buffer as appropriate. + // Init the character pointer into the o_data buffer. + // Take care of Endianess by moving to one or the other end of the + // buffer as appropriate. #ifdef _BIG_ENDIAN to_ptr = (char*)&o_data + (TRANSACTION_SIZE_IN_BYTES - i_size); #else to_ptr = ((char*)&o_data + i_size -1); #endif - for( cnt = 0; cnt < i_size; cnt++ ) - { - *to_ptr = *from_ptr++; + for( cnt = 0; cnt < i_size; cnt++ ) + { + *to_ptr = *from_ptr++; - // Move the to pointer either forward or backward as appropriate for Endianess + // Move the to pointer either forward or backward as appropriate + // for Endianess #ifdef _BIG_ENDIAN - to_ptr++; + to_ptr++; #else - to_ptr--; + to_ptr--; #endif - } + } - me = ME_SUCCESS; - break; - }while(1); + me = ME_SUCCESS; + break; + } while(0); #if POREVE_STATISTICS - iv_fetches++; + iv_fetches++; #endif return me; @@ -562,7 +610,8 @@ ModelError Memory::write( uint32_t i_offset, // the address in the eprom image uint64_t i_data, // data to write into the eprom image - size_t i_size // number of bytes to write (pretty much going to be TRANSACTION_SIZE_IN_BYTES) + size_t i_size // number of bytes to write (pretty much going to be + // TRANSACTION_SIZE_IN_BYTES) ) { char* to_ptr; @@ -573,68 +622,75 @@ Memory::write( int mi_found; me = ME_SUCCESS; - do{ + do + { if( iv_images == 0 ) { me = ME_NOT_MAPPED_IN_MEMORY; break; } - mi = iv_images; - mi_found = 0; - do{ - - if( (i_offset >= mi->iv_base) && ((i_offset + i_size) <= (mi->iv_base + mi->iv_size) ) ) + mi = iv_images; + mi_found = 0; + do { - mi_found= 1; - iv_images = mi; // have the Memory always point to the last MemoryImage that was used - break; // we found a chunk of memory containing the transaction address - } - mi = mi->iv_next; + if( (i_offset >= mi->iv_base) && + ((i_offset + i_size) <= (mi->iv_base + mi->iv_size) ) ) + { + mi_found= 1; + iv_images = mi; // have the Memory always point to the last + // MemoryImage that was used + break; // we found a chunk of memory containing the + // transaction address + } + mi = mi->iv_next; - }while( mi != iv_images ); + } while( mi != iv_images ); - if( ! mi_found ) - { // There was no MemoryImage that contained the transaction address - me = ME_NOT_MAPPED_IN_MEMORY; - break; - } + if( ! mi_found ) + { // There was no MemoryImage that contained the transaction address + me = ME_NOT_MAPPED_IN_MEMORY; + break; + } - if( (mi->iv_permissions & ACCESS_MODE_WRITE ) == 0 ) - { // The permissions over the memory block do not allow the mode being used by the transaction - me = ME_MEMORY_IMAGE_PERMISSION_DENIED; - break; - } + if( (mi->iv_permissions & ACCESS_MODE_WRITE ) == 0 ) + { // The permissions over the memory block do not allow the mode + // being used by the transaction + me = ME_MEMORY_IMAGE_PERMISSION_DENIED; + break; + } - // Init the character pointer into the eprom image we are using. - to_ptr = (char*)mi->iv_image + i_offset; + // Init the character pointer into the eprom image we are using. + to_ptr = (char*)mi->iv_image + i_offset; - // Init the character pointer into the o_data buffer. - // Take care of Endianess by moving to one or the other end of the buffer as appropriate. + // Init the character pointer into the o_data buffer. + // Take care of Endianess by moving to one or the other end of the + // buffer as appropriate. #ifdef _BIG_ENDIAN from_ptr = (char*)&i_data + (TRANSACTION_SIZE_IN_BYTES - i_size); #else from_ptr = ((char*)&i_data + i_size -1); #endif - for( cnt = 0; cnt < i_size; cnt++ ) - { - *to_ptr++ = *from_ptr; + for( cnt = 0; cnt < i_size; cnt++ ) + { + *to_ptr++ = *from_ptr; - // Move the to pointer either forward or backward as appropriate for Endianess + // Move the to pointer either forward or backward as appropriate + // for Endianess #ifdef _BIG_ENDIAN - from_ptr++; + from_ptr++; #else - from_ptr--; + from_ptr--; #endif - } + } - me = ME_SUCCESS; - break; + me = ME_SUCCESS; + break; - }while(1); + } while(0); #if POREVE_STATISTICS - iv_writes++; + iv_writes++; #endif return me; @@ -644,8 +700,9 @@ Memory::write( //----------------------------------------------------------------------------- ModelError Memory::map( - uint32_t i_base, // For direct memory this is the 0 based offset from the Slave iv_base - size_t i_size, // Size of this chunk of memory + uint32_t i_base, // For direct memory this is the 0 based offset + // from the Slave iv_base + size_t i_size, // Size of this chunk of memory int i_permissions, void* i_image, bool i_crcEnable @@ -653,20 +710,23 @@ Memory::map( { ModelError me = ME_SUCCESS; MemoryImage* n; - MemoryImage* mi = new MemoryImage( i_base, i_size, i_permissions, i_image, i_crcEnable ); + MemoryImage* mi = new MemoryImage( i_base, i_size, i_permissions, + i_image, i_crcEnable ); if( iv_images == 0 ) { - iv_images = mi; - mi->iv_next = mi; - }else{ - n = iv_images->iv_next; - while( n->iv_next != iv_images ) - { - n = n->iv_next; - } - n->iv_next = mi; - mi->iv_next = iv_images; + iv_images = mi; + mi->iv_next = mi; + } + else + { + n = iv_images->iv_next; + while( n->iv_next != iv_images ) + { + n = n->iv_next; + } + n->iv_next = mi; + mi->iv_next = iv_images; } return me; @@ -701,7 +761,6 @@ MemoryImage::MemoryImage( iv_image = i_image; iv_crcEnable = i_crcEnable; iv_originalCrc = 0; - iv_next = NULL; if( i_crcEnable ) { @@ -742,7 +801,7 @@ MemoryImage::checkCrc() //----------------------------------------------------------------------------- OciMemory::OciMemory() : -iv_memory(NULL), iv_passThrough(false) + iv_passThrough(false) { } @@ -785,12 +844,14 @@ fapi::ReturnCode OciMemory::operation(Transaction& io_transaction) { fapi::ReturnCode rc; - ModelError me; + FAPI_SET_HWP_ERROR(rc, RC_POREVE_BUS_OPERATION_ERROR); + if( io_transaction.iv_mode & ACCESS_MODE_READ ) { - me = iv_memory->read( (uint32_t)io_transaction.iv_offset, io_transaction.iv_data, TRANSACTION_SIZE_IN_BYTES ); + me = iv_memory->read( (uint32_t)io_transaction.iv_offset, + io_transaction.iv_data, TRANSACTION_SIZE_IN_BYTES ); if( me == ME_NOT_MAPPED_IN_MEMORY && iv_passThrough ) { rc = read( io_transaction.iv_address, io_transaction.iv_data ); @@ -806,7 +867,8 @@ OciMemory::operation(Transaction& io_transaction) } else { - me = iv_memory->write( (uint32_t)io_transaction.iv_offset, io_transaction.iv_data, TRANSACTION_SIZE_IN_BYTES ); + me = iv_memory->write( (uint32_t)io_transaction.iv_offset, + io_transaction.iv_data, TRANSACTION_SIZE_IN_BYTES ); if( me == ME_NOT_MAPPED_IN_MEMORY && iv_passThrough ) { rc = write( io_transaction.iv_address, io_transaction.iv_data ); @@ -823,12 +885,7 @@ OciMemory::operation(Transaction& io_transaction) io_transaction.busError( me ); - if( me == ME_SUCCESS ) - { - rc = (uint32_t)0; - } - - // if read/write failed then rc == 1 by default + // if read/write failed then rc == RC_BUS_OPERATION_ERROR by default // if read/write returned ME_NOT_MAPPED_IN_MEMORY && pass through true then // rc == value returned from putScom or getScom @@ -875,6 +932,7 @@ fapi::ReturnCode OciSlave::read(const uint32_t i_address, uint64_t& o_data) { fapi::ReturnCode rc; + FAPI_SET_HWP_ERROR(rc, RC_POREVE_BUS_OCI_SLAVE_READ_NOT_SUPPORTED); return rc; } @@ -883,6 +941,7 @@ fapi::ReturnCode OciSlave::write(const uint32_t i_address, const uint64_t i_data) { fapi::ReturnCode rc; + FAPI_SET_HWP_ERROR(rc, RC_POREVE_BUS_OCI_SLAVE_WRITE_NOT_SUPPORTED); return rc; } @@ -890,8 +949,6 @@ OciSlave::write(const uint32_t i_address, const uint64_t i_data) fapi::ReturnCode OciSlaveWritable::write(const uint32_t i_address, const uint64_t i_data) { - - // For this model, print out a message to confirm a write has been written is all it needs. FAPI_INF("OciSlaveWritable::write(0x%08x, 0x%016llx)", i_address, i_data); fapi::ReturnCode rc; diff --git a/src/usr/pore/poreve/porevesrc/bus.H b/src/usr/pore/poreve/porevesrc/bus.H index 6370bae84..4f4a93ef1 100644 --- a/src/usr/pore/poreve/porevesrc/bus.H +++ b/src/usr/pore/poreve/porevesrc/bus.H @@ -1,25 +1,26 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/pore/poreve/porevesrc/bus.H $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2012 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/poreve/porevesrc/bus.H $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ #ifndef __VSBE_BUS_H #define __VSBE_BUS_H @@ -624,8 +625,10 @@ public: uint64_t i_data, size_t i_size); +private: /// Pointer to first MemoryImage in a circularly linked list MemoryImage* iv_images; +public: #if POREVE_STATISTICS diff --git a/src/usr/pore/poreve/porevesrc/dbg.C b/src/usr/pore/poreve/porevesrc/dbg.C new file mode 100644 index 000000000..87add7759 --- /dev/null +++ b/src/usr/pore/poreve/porevesrc/dbg.C @@ -0,0 +1,108 @@ +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/poreve/porevesrc/dbg.C $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ +// $Id: dbg.C,v 1.3 2011/06/07 03:10:45 bcbrock Exp $ + +/// \file dbg.C +/// \brief The PORE Virtual Environment - Debugged +/// +/// This file includes the PoreVeDbg constructor and the create() and run() +/// methods for PoreVeDbg. The pdbg::entryPoint is left as an unresolved +/// external at link time and defined in the debugging environment code. + +#include <stdio.h> +#include <string.h> +#include "dbg.H" + +using namespace vsbe; + +namespace pdbg { + /// Start the \c pdbg debugger + /// + /// \param[in] i_instructions Currently ignored + /// + /// \param[out] o_ran Currently ignored + /// + /// \param[in] i_arg The name of a debugger script to run at + /// initialization. + /// + /// This is the entry point used to initiate the pdbg interactive + /// debugger. It is called from the PoreVeDbg::run() method the first time + /// that method is called. Note: pdbg::entryPoint currently doesn't + /// return. + int entryPoint(const uint64_t i_instructions, + uint64_t& o_ran, + const char* i_arg); +} + + +//////////////////////////////////////////////////////////////////////////// +// PoreVeDbg +//////////////////////////////////////////////////////////////////////////// + +PoreVeDbg* PoreVeDbg::cv_instance = 0; + + +PoreVeDbg::PoreVeDbg(const PoreIbufId i_id, + const fapi::Target i_masterTarget, + const void* i_arg) : + PoreVe(i_id, i_masterTarget), + iv_initialized(false) +{ + iv_arg = strdup((char*)i_arg); + cv_instance = this; +} + + +PoreVeDbg::~PoreVeDbg() +{ + free(iv_arg); +} + + +int +PoreVeDbg::run(const uint64_t i_instructions, uint64_t& o_ran) +{ + if (iv_initialized) { + return PoreVe::run(i_instructions, o_ran); + } else { + iv_initialized = true; + return pdbg::entryPoint(i_instructions, o_ran, iv_arg); + } +} + + +PoreVe* +PoreVe::create(const PoreIbufId i_id, + const fapi::Target i_masterTarget, + const void* i_arg) +{ + return new PoreVeDbg(i_id, i_masterTarget, i_arg); +} + + + + + + + diff --git a/src/usr/pore/poreve/porevesrc/dbg.H b/src/usr/pore/poreve/porevesrc/dbg.H new file mode 100644 index 000000000..cb085d729 --- /dev/null +++ b/src/usr/pore/poreve/porevesrc/dbg.H @@ -0,0 +1,115 @@ +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/poreve/porevesrc/dbg.H $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ +#ifndef __VSBE_POREVEDBG_H +#define __VSBE_POREVEDBG_H + +// $Id: dbg.H,v 1.2 2011/06/03 19:50:19 jeshua Exp $ + +/// \file dbg.H +/// \brief The PORE Virtual Environment - Debugged + +#include "poreve.H" + +namespace vsbe { + class PoreVeDbg; +}; + + +//////////////////////////////////////////////////////////////////////////// +// PoreVeDbg +//////////////////////////////////////////////////////////////////////////// + +/// The PoreVe Debug configuration +/// +/// This derivation from PoreVe supports the Tcl debug environment for +/// PoreVe. The constructor takes an extra argument which is a character +/// string containing the name of a script (file) to run when the debugger +/// starts. + +class +vsbe::PoreVeDbg : public vsbe::PoreVe { + +public: + + ////////////////////////////// Creators ////////////////////////////// + + /// Construct the PoreVeDbg + /// + /// \param[in] i_id The PORE IBUF_ID (engine type) of the Pore component. + /// This will be PORE_SBE for host boot/SBE applications, and PORE_SLW for + /// testing Sleep/Winkle applications. + /// + /// \param[in] i_masterTarget The fapi::Target associated with the master + /// chip in an HBI master/slave configuration. This target is also + /// installed into \a iv_slaveTarget by the constructor. + /// + /// \param[in] i_arg A private argument for the created model. In the + /// case of this debugged model this is a character string naming a script + /// to be run when the debugger starts. + PoreVeDbg(const PoreIbufId i_id, + const fapi::Target i_masterTarget, + const void* i_arg); + + virtual ~PoreVeDbg(); + + + //////////////////// Simulation Interface ///////////////////////// + + /// See PoreModel::run() + /// + /// This API is provided as a convenience. Currently the only model in + /// the system that is 'clocked' is the PoreModel. + virtual int + run(const uint64_t i_instructions, uint64_t& o_ran); + + + //////////////////// Public Implementation //////////////////////////// + + /// PoreVeDbg is a singleton class, and this is the singleton instance. + static PoreVeDbg* cv_instance; + + + //////////////////// Protected Implementation ////////////////////////// + +protected: + + /// The argument passed at creation + char* iv_arg; + + /// Used by the run() method. + /// + /// The first time run() is called on the debug model the debugging + /// environment is initialized and any script specified at creation is + /// executed. + bool iv_initialized; + + + ///////////////////////////// Safety ////////////////////////////////// + +private: + PoreVeDbg(const PoreVeDbg& i_rhs); + PoreVeDbg& operator=(const PoreVeDbg& i_rhs); +}; + +#endif // __VSBE_POREVEDBG_H diff --git a/src/usr/pore/poreve/porevesrc/fasti2c.C b/src/usr/pore/poreve/porevesrc/fasti2c.C index 676fdccda..b0152e130 100644 --- a/src/usr/pore/poreve/porevesrc/fasti2c.C +++ b/src/usr/pore/poreve/porevesrc/fasti2c.C @@ -1,26 +1,27 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/pore/poreve/porevesrc/fasti2c.C $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2012 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END -// $Id: fasti2c.C,v 1.5 2012/01/10 00:27:41 bcbrock Exp $ +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/poreve/porevesrc/fasti2c.C $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ +// $Id: fasti2c.C,v 1.6 2012/05/23 19:51:39 bcbrock Exp $ /// \file fasti2c.C /// \brief The "fast-mode" I2C controllers and I2C memory models used @@ -43,8 +44,7 @@ using namespace vsbe; // I2cMemory //////////////////////////////////////////////////////////////////////////// -I2cMemory::I2cMemory(const size_t i_addressBytes) : -iv_addressBytes(i_addressBytes), iv_address(0) +I2cMemory::I2cMemory() { } @@ -54,6 +54,13 @@ I2cMemory::~I2cMemory() } +void +I2cMemory::configure(const uint8_t i_bytes) +{ + iv_addressBytes = i_bytes; +} + + ModelError I2cMemory::addressWrite(const size_t i_bytes, const uint32_t i_address) { @@ -102,11 +109,9 @@ I2cMemory::dataWrite(const size_t i_bytes, const uint64_t i_data) FastI2cController::FastI2cController() : iv_devices(0), - iv_state(IDLE), iv_fifo(0) - + iv_state(IDLE) { iv_status.value = 0; - iv_control.value = 0; } @@ -128,8 +133,8 @@ FastI2cController::~FastI2cController() ModelError FastI2cController::attachMemory(I2cMemory* i_memory, - const unsigned i_port, - const unsigned i_deviceAddress) + const uint8_t i_port, + const uint8_t i_deviceAddress) { ModelError me = ME_SUCCESS; FastI2cControlRegister control; // Used to validate i_Port and i_deviceId @@ -137,7 +142,6 @@ FastI2cController::attachMemory(I2cMemory* i_memory, control.fields.port_number = i_port; control.fields.device_address = i_deviceAddress; - // Make sure input variables fits into control fields if ((control.fields.port_number != i_port) || (control.fields.device_address != i_deviceAddress)) { BUG(); @@ -353,7 +357,7 @@ FastI2cController::operation(Transaction& io_transaction) if (me != 0) { iv_state = ERROR; - rc = 1; // \bug Fix this + FAPI_SET_HWP_ERROR(rc, RC_POREVE_FASTI2C_OPERATION_ERROR); } io_transaction.busError(me); return rc; @@ -586,7 +590,7 @@ LpcController::operation(Transaction& io_transaction) } if (!handledBySuperclass) { if (me != 0) { - rc = 1; // \bug Fix this; + FAPI_SET_HWP_ERROR(rc, RC_POREVE_LPC_OPERATION_ERROR); } io_transaction.busError(me); } diff --git a/src/usr/pore/poreve/porevesrc/fasti2c.H b/src/usr/pore/poreve/porevesrc/fasti2c.H index a21288e94..6c179c338 100644 --- a/src/usr/pore/poreve/porevesrc/fasti2c.H +++ b/src/usr/pore/poreve/porevesrc/fasti2c.H @@ -1,29 +1,30 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/pore/poreve/porevesrc/fasti2c.H $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2012 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/poreve/porevesrc/fasti2c.H $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ #ifndef __VSBE_FASTI2C_H #define __VSBE_FASTI2C_H -// $Id: fasti2c.H,v 1.5 2011/12/16 20:27:26 bcbrock Exp $ +// $Id: fasti2c.H,v 1.6 2012/05/23 19:51:40 bcbrock Exp $ /// \file fasti2c.H /// \brief The "fast-mode" I2C controllers and memory models used @@ -243,10 +244,7 @@ public: ////////////////////////////// Creators ////////////////////////////// /// Create an I2c Memory - /// - /// \param[in] i_addressBytes The number of bytes (1-4) in a memory - /// address for this memory. - I2cMemory(const size_t i_addressBytes); + I2cMemory(); virtual ~I2cMemory(); @@ -254,6 +252,13 @@ public: //////////////////////////// Manipulators //////////////////////////// + /// Configure the number of address bytes + /// + /// \param[in] i_addressBytes The number of address bytes (1-4) in a + /// memory address for this devie. + void + configure(const uint8_t i_addressBytes); + /// Perform an I2C address write to an attached device. /// /// \param[in] i_bytes The number of address bytes, which must match the @@ -297,7 +302,7 @@ public: protected: /// The number of address bytes (1-4) - const size_t iv_addressBytes; + uint8_t iv_addressBytes; /// The address register, auto-incremented on data reads and writes uint32_t iv_address; @@ -412,8 +417,8 @@ public: /// ME_AMBIGUOUS_CONFIGURATION. ModelError attachMemory(I2cMemory* i_memory, - const unsigned i_port, - const unsigned i_deviceAddress); + const uint8_t i_port, + const uint8_t i_deviceAddress); /// Handle a PIB transaction /// diff --git a/src/usr/pore/poreve/porevesrc/hookmanager.C b/src/usr/pore/poreve/porevesrc/hookmanager.C index bf31e76b1..e963500a7 100644 --- a/src/usr/pore/poreve/porevesrc/hookmanager.C +++ b/src/usr/pore/poreve/porevesrc/hookmanager.C @@ -1,25 +1,26 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/pore/poreve/porevesrc/hookmanager.C $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2012 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/poreve/porevesrc/hookmanager.C $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ // $Id: hookmanager.C,v 1.12 2012/01/06 21:25:25 bcbrock Exp $ /// \file hookmanager.C @@ -41,10 +42,25 @@ using namespace vsbe; #endif fapi::ReturnCode vsbe::hookOk; + HookManager* HookManager::s_instance = 0; //////////////////////////////////////////////////////////////////////////// +// PoreAddressComparison +//////////////////////////////////////////////////////////////////////////// + +bool +PoreAddressComparison::operator()(PoreAddress const& i_lhs, + PoreAddress const& i_rhs) const +{ + return + (i_lhs.iv_memorySpace < i_rhs.iv_memorySpace) || + (i_lhs.iv_offset < i_rhs.iv_offset); +} + + +//////////////////////////////////////////////////////////////////////////// // CharPointerComparison //////////////////////////////////////////////////////////////////////////// @@ -573,3 +589,4 @@ HookInitializer::HookInitializer(HookManagerInitializer i_function) HookInitializer::~HookInitializer() { } + diff --git a/src/usr/pore/poreve/porevesrc/hookmanager.H b/src/usr/pore/poreve/porevesrc/hookmanager.H index 5323392c9..2b86659ee 100644 --- a/src/usr/pore/poreve/porevesrc/hookmanager.H +++ b/src/usr/pore/poreve/porevesrc/hookmanager.H @@ -1,25 +1,26 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/pore/poreve/porevesrc/hookmanager.H $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2012 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/poreve/porevesrc/hookmanager.H $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ #ifndef __VSBE_HOOKMANAGER_H #define __VSBE_HOOKMANAGER_H @@ -301,6 +302,35 @@ namespace vsbe { /// This class defines the comparison operator for STL containers using a /// PoreAddress as the key. +class +vsbe::PoreAddressComparison { + +public: + + PoreAddressComparison() {} + + ~PoreAddressComparison() {} + + /// Compare PoreAddress* + /// + /// \param[in] i_lhs Left hand side object + /// + /// \param[in] i_rhs Right hand side object + /// + /// \retval rc This is a simple lexicographic order on the segment and + /// offset. + bool operator() (PoreAddress const& i_lhs, + PoreAddress const& i_rhs) const; + + + ///////////////////////////// Safety ////////////////////////////////// + +private: + // STL requires a copy operator + PoreAddressComparison& operator=(const PoreAddressComparison& rhs); +}; + + //////////////////////////////////////////////////////////////////////////// // CharPointerComparison //////////////////////////////////////////////////////////////////////////// @@ -435,6 +465,8 @@ public: ////////////////////////////// Creators ////////////////////////////// + HookManager(); + virtual ~HookManager(); ///////////////////////////// Accessors ////////////////////////////// @@ -809,7 +841,6 @@ protected: ///////////////////////////// Safety ////////////////////////////////// private: - HookManager(); HookManager(const HookManager& i_rhs); HookManager& operator=(const HookManager& i_rhs); }; diff --git a/src/usr/pore/poreve/porevesrc/pib2cfam.C b/src/usr/pore/poreve/porevesrc/pib2cfam.C index 648df8822..82cabe313 100644 --- a/src/usr/pore/poreve/porevesrc/pib2cfam.C +++ b/src/usr/pore/poreve/porevesrc/pib2cfam.C @@ -1,27 +1,28 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/pore/poreve/porevesrc/pib2cfam.C $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2012 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/poreve/porevesrc/pib2cfam.C $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ // -*- mode: C++; c-file-style: "linux"; -*- -// $Id: pib2cfam.C,v 1.10 2012/02/27 22:52:31 jeshua Exp $ +// $Id: pib2cfam.C,v 1.11 2012/04/02 16:27:58 jeshua Exp $ /// \file pib2cfam.C /// \brief A simple PibSlave that maps a small range of PIB addresses to CFAM @@ -53,9 +54,7 @@ translateAddress(uint32_t address, fapi::Target* i_target) frc = FAPI_ATTR_GET( ATTR_FSI_GP_REG_SCOM_ACCESS, i_target, fsi_gpreg_scom_access ); if(!frc.ok()) { - FAPI_ERR( "Unable to get ATTR_FSI_GP_REG_SCOM_ACCESS for target\n" ); -//JDS TODO - create an actual fapi error -// FAPI_SET_HWP_ERROR( frc, "Unable to get ATTR_FSI_GP_REG_SCOM_ACCESS for target\n" ); + FAPI_ERR( "Unable to get ATTR_FSI_GP_REG_SCOM_ACCESS for target" ); } @@ -84,6 +83,8 @@ Pib2Cfam::operation(Transaction& io_transaction) case 0x00050014: case 0x00050015: case 0x00050016: + case 0x00050017: + case 0x00050018: case 0x00050019: case 0x0005001A: case 0x0005001B: @@ -99,6 +100,7 @@ Pib2Cfam::operation(Transaction& io_transaction) } break; default: + FAPI_SET_HWP_ERROR(rc,RC_POREVE_PIB2CFAM_ME_NOT_MAPPED_IN_MEMORY); me = ME_NOT_MAPPED_IN_MEMORY; } break; @@ -112,6 +114,8 @@ Pib2Cfam::operation(Transaction& io_transaction) case 0x00050014: case 0x00050015: case 0x00050016: + case 0x00050017: + case 0x00050018: case 0x0005001B: iv_dataBuffer->setWordLength(1); iv_dataBuffer->setWord(0, io_transaction.iv_data >> 32); @@ -127,18 +131,20 @@ Pib2Cfam::operation(Transaction& io_transaction) case 0x00050019: case 0x0005001A: - rc = 1; + FAPI_SET_HWP_ERROR(rc, + RC_POREVE_PIB2CFAM_ME_BUS_SLAVE_PERMISSION_DENIED); me = ME_BUS_SLAVE_PERMISSION_DENIED; break; default: - rc = 1; + FAPI_SET_HWP_ERROR(rc,RC_POREVE_PIB2CFAM_ME_NOT_MAPPED_IN_MEMORY); me = ME_NOT_MAPPED_IN_MEMORY; } break; default: - rc = 1; + FAPI_SET_HWP_ERROR(rc, + RC_POREVE_PIB2CFAM_ME_BUS_SLAVE_PERMISSION_DENIED); me = ME_BUS_SLAVE_PERMISSION_DENIED; break; } diff --git a/src/usr/pore/poreve/porevesrc/pibmem.C b/src/usr/pore/poreve/porevesrc/pibmem.C new file mode 100644 index 000000000..2134c4d58 --- /dev/null +++ b/src/usr/pore/poreve/porevesrc/pibmem.C @@ -0,0 +1,314 @@ +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/poreve/porevesrc/pibmem.C $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ +// $Id: pibmem.C,v 1.1 2012/02/29 20:58:38 bcbrock Exp $ + +/// \file pibmem.C +/// \brief A model of the P8 "PIB-attached Memory" + +#include "pibmem.H" + +using namespace vsbe; + +#ifndef VERBOSE +#define VERBOSE 0 +#endif + +////////////////////////////// Creators ////////////////////////////// + +Pibmem::Pibmem(const size_t i_memorySize) : + iv_memorySize(i_memorySize) +{ + reset(); +} + + +Pibmem::~Pibmem() +{ +} + + +//////////////////////////// Manipulators //////////////////////////// + + +// Model direct and indirect access to memory and control registers. Note +// that by specification, post inc/dec takes place even if the indirect access +// takes an error. + +fapi::ReturnCode +Pibmem::operation(Transaction& io_transaction) +{ + fapi::ReturnCode rc; + + // The transaction is initially marked as successful, but may later pick + // up PIB error codes. + + io_transaction.busError(ME_SUCCESS); + + + // Split on direct vs. indirect accesses + + if (io_transaction.iv_offset < PIBMEM_CONTROL_BASE) { + + // These are simple direct PIB read/write of memory + + rc = memoryOperation(io_transaction, true); + + if (VERBOSE) { + FAPI_DBG("PIBMEM : Direct to 0x%08x, %s 0x%016llx", + io_transaction.iv_offset, + ((io_transaction.iv_mode == ACCESS_MODE_WRITE) ? + "Write" : ((io_transaction.iv_mode == ACCESS_MODE_READ) ? + "Read" : "Execute")), + io_transaction.iv_data); + } + + } else { + + switch (io_transaction.iv_mode) { + + case ACCESS_MODE_READ: + case ACCESS_MODE_EXECUTE: + + // Register reads and indirect memory reads + + switch (io_transaction.iv_offset) { + + case PIBMEM_CONTROL: + io_transaction.iv_data = iv_control.value; + break; + + case PIBMEM_ADDRESS: + io_transaction.iv_data = iv_address.value; + break; + + case PIBMEM_STATUS: + io_transaction.iv_data = iv_status.value; + break; + + case PIBMEM_RESET: + io_transaction.iv_data = iv_reset.value; + break; + + case PIBMEM_REPAIR: + io_transaction.iv_data = iv_repair; + break; + + case PIBMEM_DATA: + rc = memoryOperation(io_transaction, false); + break; + + case PIBMEM_DATA_INC: + if (iv_control.fields.auto_pre_increment) { + incrAddress(1); + } + rc = memoryOperation(io_transaction, false); + if (!iv_control.fields.auto_pre_increment) { + incrAddress(1); + } + break; + + case PIBMEM_DATA_DEC: + if (!iv_control.fields.auto_post_decrement) { + incrAddress(-1); + } + rc = memoryOperation(io_transaction, false); + if (iv_control.fields.auto_post_decrement) { + incrAddress(-1); + } + break; + + default: + FAPI_SET_HWP_ERROR(rc, RC_POREVE_PIBMEM_BAD_OFFSET); // Bug + break; + } + + break; + + case ACCESS_MODE_WRITE: + + // Register writes and indirect memory writes + + switch (io_transaction.iv_offset) { + + case PIBMEM_CONTROL: + iv_control.value = + io_transaction.iv_data & PIBMEM_CONTROL_DEFINED; + break; + + case PIBMEM_ADDRESS: + iv_address.value = + io_transaction.iv_data & PIBMEM_ADDRESS_DEFINED; + break; + + case PIBMEM_STATUS: + // Read-only + break; + + case PIBMEM_RESET: + iv_reset.value = + io_transaction.iv_data & PIBMEM_RESET_DEFINED; + if (iv_reset.fields.reset_code == PIBMEM_RESET_CODE) { + reset(); + } + break; + + case PIBMEM_REPAIR: + // Behavior of this register is beyond the scope of the model + iv_repair = io_transaction.iv_data; + break; + + case PIBMEM_DATA: + rc = memoryOperation(io_transaction, false); + break; + + case PIBMEM_DATA_INC: + if (iv_control.fields.auto_pre_increment) { + incrAddress(1); + } + rc = memoryOperation(io_transaction, false); + if (!iv_control.fields.auto_pre_increment) { + incrAddress(1); + } + break; + + case PIBMEM_DATA_DEC: + if (!iv_control.fields.auto_post_decrement) { + incrAddress(-1); + } + rc = memoryOperation(io_transaction, false); + if (iv_control.fields.auto_post_decrement) { + incrAddress(-1); + } + break; + + default: + FAPI_SET_HWP_ERROR(rc, RC_POREVE_PIBMEM_BAD_OFFSET); // Bug + break; + } + + break; + + default: + FAPI_SET_HWP_ERROR(rc, RC_POREVE_PIBMEM_BAD_MODE); // Bug + break; + } + + if (VERBOSE) { + FAPI_DBG("PIBMEM : Indirect to 0x%08x, %s 0x%016llx", + io_transaction.iv_offset, + ((io_transaction.iv_mode == ACCESS_MODE_WRITE) ? + "Write" : ((io_transaction.iv_mode == ACCESS_MODE_READ) ? + "Read" : "Execute")), + io_transaction.iv_data); + } + + } + + return rc; +} + + +////////////////////////// Implementation ////////////////////////////////// + + +// Note the differences in the error return codes for the error cases. Asking +// for memory that does not exist in the hardware gives a normal return with a +// PIB 'address error' status code. If the access was indirect then the +// PCB_PACKET_ERROR code is returned. Asking for memory that has not been +// mapped by the application yields a model error and a FAPI error. + +fapi::ReturnCode +Pibmem::memoryOperation(Transaction& io_transaction, + const bool i_direct) +{ + fapi::ReturnCode rc; + uint32_t saveOffset; + + if (i_direct) { + if (io_transaction.iv_offset >= iv_memorySize) { + + iv_status.fields.addr_invalid = 1; + if (io_transaction.iv_mode == ACCESS_MODE_WRITE) { + iv_status.fields.write_invalid = 1; + } else { + iv_status.fields.read_invalid = 1; + } + ((PibTransaction&)io_transaction).iv_pcbReturnCode = + PCB_ADDRESS_ERROR; + + } else { + + rc = PibMemory::operation(io_transaction); + + } + + } else { + + if (io_transaction.iv_offset >= iv_memorySize) { + + iv_status.fields.bad_array_address = 1; + ((PibTransaction&)io_transaction).iv_pcbReturnCode = + PCB_PACKET_ERROR; + } else { + + saveOffset = io_transaction.iv_offset; + io_transaction.iv_offset = iv_address.fields.address_pointer; + rc = PibMemory::operation(io_transaction); + io_transaction.iv_offset = saveOffset; + + } + } + + return rc; +} + + +void +Pibmem::incrAddress(const int i_incr) +{ + iv_address.fields.address_pointer = + iv_address.fields.address_pointer + i_incr; +} + + +void +Pibmem::reset() { + iv_control.value = 0; + iv_address.value = 0; + iv_status.value = 0; + iv_reset.value = 0; + iv_data = 0; + iv_dataInc = 0; + iv_dataDec = 0; + iv_repair = 0; + + // The reset state (and subsequent status reads) show the FSM idle + // state + + iv_status.fields.fsm_present_state = PIBMEM_FSM_IDLE; +} + +/* Local Variables: */ +/* c-basic-offset: 4 */ +/* End: */ diff --git a/src/usr/pore/poreve/porevesrc/pibmem.H b/src/usr/pore/poreve/porevesrc/pibmem.H new file mode 100644 index 000000000..205f114e6 --- /dev/null +++ b/src/usr/pore/poreve/porevesrc/pibmem.H @@ -0,0 +1,239 @@ +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/poreve/porevesrc/pibmem.H $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ +#ifndef __VSBE_PIBMEM_H +#define __VSBE_PIBMEM_H + +// $Id: pibmem.H,v 1.2 2012/05/21 13:20:34 bcbrock Exp $ + +/// \file pib2mem.H +/// \brief A model of the P8 "PIB-attached Memory" +/// +/// PIBMEM is a PIB-attached memory that provides direct SCOM access to its +/// memory array starting at PIB local address 0, as well as indirect +/// addressing modes through control/data registers at offset 0x8000. +/// Addressing modes include simple indirect addressing as well as +/// configurable pre/post increment/decrement addressing. +/// +/// Pibmem is derived from PibMemory - which provides the low-level +/// configuration and memory accesses. This model extends PibMemory by the +/// addition of a set of control and status registers. +/// +/// \todo Nail down why the spec. has separate error bits for illegal +/// addresses, and non-read(write)able addresses. + +#include "bebits.H" +#include "bus.H" + +namespace vsbe { + + class Pibmem; + + // PIBMEM register offsets + + const uint32_t PIBMEM_CONTROL_BASE = 0x8000; + + const uint32_t PIBMEM_CONTROL = 0x8000; + const uint32_t PIBMEM_ADDRESS = 0x8001; + const uint32_t PIBMEM_DATA = 0x8002; + const uint32_t PIBMEM_DATA_INC = 0x8003; + const uint32_t PIBMEM_DATA_DEC = 0x8004; + const uint32_t PIBMEM_STATUS = 0x8005; + const uint32_t PIBMEM_RESET = 0x8006; + const uint32_t PIBMEM_REPAIR = 0x8007; + + /// The PIBMEM maps this many SCOM addresses, including its control space + const uint32_t PIBMEM_PIB_SIZE = 0x8008; + + /// The value to write to control.reset_code to cause a reset. + const uint32_t PIBMEM_RESET_CODE = 2; + + /// The encoding of the PIBMEM FSM idle state + const uint32_t PIBMEM_FSM_IDLE = 0x40; + + + /// The Pibmem control register controls auto inc/dec modes + typedef union { + uint64_t value; + struct { +#ifdef _BIG_ENDIAN + uint64_t auto_pre_increment : 1; + uint64_t auto_post_decrement : 1; + uint64_t reserved : 62; +#else + uint64_t reserved : 62; + uint64_t auto_post_decrement : 1; + uint64_t auto_pre_increment : 1; +#endif + } fields; + } PibmemControl; + + const uint64_t PIBMEM_CONTROL_DEFINED = BE64_MASK(0, 1); + + + /// The Pibmem address register only defines 16 address bits + typedef union { + uint64_t value; + struct { +#ifdef _BIG_ENDIAN + uint64_t reserved : 48; + uint64_t address_pointer : 16; +#else + uint64_t address_pointer : 16; + uint64_t reserved : 48; +#endif + } fields; + } PibmemAddress; + + const uint64_t PIBMEM_ADDRESS_DEFINED = BE64_MASK(48, 63); + + + /// We model the PIBMEM status register, except for the ECC error bits and + /// the FSM state (which always reports as IDLE in this model). The + /// status register is read-only, and only reset by a hard reset. + typedef union { + uint64_t value; + struct { +#ifdef _BIG_ENDIAN + uint64_t addr_invalid : 1; + uint64_t write_invalid : 1; + uint64_t read_invalid : 1; + uint64_t ecc_uncorrected_error : 1; + uint64_t ecc_corrected_error : 1; + uint64_t bad_array_address : 1; + uint64_t reserved0 : 5; + uint64_t fsm_present_state : 7; + uint64_t reserved1 : 46; +#else + uint64_t reserved1 : 46; + uint64_t fsm_present_state : 7; + uint64_t reserved0 : 5; + uint64_t bad_array_address : 1; + uint64_t ecc_corrected_error : 1; + uint64_t ecc_uncorrected_error : 1; + uint64_t read_invalid : 1; + uint64_t write_invalid : 1; + uint64_t addr_invalid : 1; +#endif + } fields; + } PibmemStatus; + + + /// The 'reset_code' must be written with 0b10 to reset the memory + typedef union { + uint64_t value; + struct { +#ifdef _BIG_ENDIAN + uint64_t reset_code : 2; + uint64_t reserved1 : 62; +#else + uint64_t reserved : 62; + uint64_t reset_code : 2; +#endif + } fields; + } PibmemReset; + + const uint64_t PIBMEM_RESET_DEFINED = BE64_MASK(0, 1); +} + + +class +vsbe::Pibmem : public PibMemory { + +public: + + ////////////////////////////// Creators ////////////////////////////// + + /// Pibmem constructor + /// + /// \param[in] i_memorySize The maximum size of the memory in units of + /// 8-byte doublewords. + Pibmem(const size_t i_memorySize); + + virtual ~Pibmem(); + + + //////////////////////////// Manipulators //////////////////////////// + + /// Pibmem operation + /// + /// \param[in,out] io_transaction A PIB transaction object + /// + /// Read/write of addresses below the control range are direct SCOM access + /// to the PIBMEM memory itself. Indirect accesses use the indirect + /// address and data register. + /// + /// \retval rc A fapi::ReturnCode denoting success or a problem. + fapi::ReturnCode + operation(Transaction& io_transaction); + + + //////////////////// Implementation ////////////////////////////////// + +protected: + + /// Implements the PIBMEM reset sequence - all state is cleared + void reset(); + + /// Pibmem memory read/write operation + /// + /// \param[in,out] io_transaction A PIB transaction object + /// + /// \param[in] i_direct Indicates whether this is a direct or indirect + /// access (for error reporting). For indirect access the address comes + /// from the address register. + /// + /// \retval rc A fapi::ReturnCode denoting success or a problem. + fapi::ReturnCode memoryOperation(Transaction& io_transaction, + const bool i_direct); + + /// Increment/decrement the indirect address register + /// + /// \param[in] i_incr The (signed) increment/decrement + void incrAddress(const int i_incr); + + /// The size of the memory in units of 8-byte doublewords + uint32_t iv_memorySize; + + // Control/status register state. Data registers have no substructure. + + PibmemControl iv_control; + PibmemAddress iv_address; + PibmemStatus iv_status; + PibmemReset iv_reset; + + uint64_t iv_data, iv_dataInc, iv_dataDec, iv_repair; + + + ///////////////////////////// Safety ////////////////////////////////// + +private: + Pibmem(const Pibmem& rhs); + Pibmem& operator=(const Pibmem& rhs); +}; + +/* Local Variables: */ +/* c-basic-offset: 4 */ +/* End: */ + +#endif // __VSBE_PIBMEM_H diff --git a/src/usr/pore/poreve/porevesrc/pore.C b/src/usr/pore/poreve/porevesrc/pore.C index 8f09e2e29..d2dd27f91 100644 --- a/src/usr/pore/poreve/porevesrc/pore.C +++ b/src/usr/pore/poreve/porevesrc/pore.C @@ -1,26 +1,27 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/pore/poreve/porevesrc/pore.C $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2012 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END -// $Id: pore.C,v 1.13 2011/11/17 19:05:22 jeshua Exp $ +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/poreve/porevesrc/pore.C $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ +// $Id: pore.C,v 1.14 2012/02/29 20:58:39 bcbrock Exp $ /// \file pore.C /// \brief The implementation of the PoreInterface for the PoreVe environment @@ -62,12 +63,21 @@ Pore::pibMaster(PibTransaction& io_transaction) if (iv_pib == 0) { me = ME_NO_BUS_MODEL; io_transaction.busError(me); - iv_fapiReturnCode = 1; /// \bug Need a return code + FAPI_SET_HWP_ERROR(iv_fapiReturnCode,RC_POREVE_ME_NO_BUS_MODEL); } else { iv_fapiReturnCode = iv_pib->operation(io_transaction); me = io_transaction.iv_modelError; } if (me != 0) { + FAPI_ERR("\nPore::pibMaster() received ModelError %d\n" + "Transaction is a %s of address 0x%08x\n" + "Transaction data is 0x%016llx", + (int)me, + ((io_transaction.iv_mode == ACCESS_MODE_WRITE) ? + "write" : ((io_transaction.iv_mode == ACCESS_MODE_READ) ? + "read" : "fetch")), + io_transaction.iv_address, + io_transaction.iv_data); modelError(me); } } @@ -81,12 +91,21 @@ Pore::ociMaster(OciTransaction& io_transaction) if (iv_oci == 0) { me = ME_NO_BUS_MODEL; io_transaction.busError(me); - iv_fapiReturnCode = 1; /// \bug Need a return code + FAPI_SET_HWP_ERROR(iv_fapiReturnCode,RC_POREVE_ME_NO_BUS_MODEL); } else { iv_fapiReturnCode = iv_oci->operation(io_transaction); me = io_transaction.iv_modelError; } if (me != 0) { + FAPI_ERR("\nPore::ociMaster() received ModelError %d\n" + "Transaction is a %s of address 0x%08x\n" + "Transaction data is 0x%016llx", + (int)me, + ((io_transaction.iv_mode == ACCESS_MODE_WRITE) ? + "write" : ((io_transaction.iv_mode == ACCESS_MODE_READ) ? + "read" : "fetch")), + io_transaction.iv_address, + io_transaction.iv_data); modelError(me); } } @@ -100,14 +119,22 @@ Pore::wait(const uint32_t i_count) fapi::ReturnCode rc; ModelError me; - nsDelay = (uint64_t)((i_count * 1e9) / PORE_FREQUENCY); - +#ifndef __HOSTBOOT_MODULE + nsDelay = (uint64_t)((i_count / PORE_FREQUENCY) * 1e9); simCycles = (uint64_t) (SIMULATOR_TICK_FREQUENCY * (i_count / PORE_FREQUENCY)); +#else + nsDelay = i_count; + nsDelay *= 1000000000ull; + nsDelay /= PORE_FREQUENCY; + simCycles = i_count; + simCycles *= SIMULATOR_TICK_FREQUENCY; + simCycles /= PORE_FREQUENCY; +#endif nsDelay += 1; // Always round up the real delay. iv_fapiReturnCode = fapiDelay(nsDelay, simCycles); - if (iv_fapiReturnCode == 0) { + if (iv_fapiReturnCode.ok()) { me = ME_SUCCESS; } else { me = ME_WAIT_FAILURE; @@ -234,8 +261,7 @@ Pore::operation(Transaction& io_transaction) Pore::Pore(PoreIbufId i_id) : PoreInterface(i_id), iv_pib(0), - iv_oci(0), - iv_target(NULL) + iv_oci(0) { } @@ -266,4 +292,86 @@ Pore::getFapiReturnCode() return iv_fapiReturnCode; } + +// The programmer-visible registers that are supported by PoreInterface (the +// first set in the dump) are obtained directly from the interface, since the +// interface already formats them correctly. The remaining registers are +// obtained from a state extraction. + +void +Pore::dump() +{ + PoreState state; + // Need 3 regs since evaluation order is not guaranteed +#ifndef __HOSTBOOT_MODULE + uint64_t reg0, reg1, reg2; +#else + uint64_t reg0 = 0, reg1 = 0, reg2 = 0; // Need to initialize + reg0 = reg0; // and use them to avoid compile error under + reg1 = reg1; // hostboot + reg2 = reg2; +#endif + + // NB : "Bugs" in eCMD FAPI_* implementation do not allow format strings + // to be variables. +#define SEPARATOR "--------------------------------------------------------" + + extractState(state); + + FAPI_DBG(SEPARATOR); + FAPI_DBG("PORE dump after %llu instructions.", + getInstructions()); + FAPI_DBG(SEPARATOR); + FAPI_DBG(" PC : %04x.%08x", + (uint32_t)(pc >> 32) & 0xffff, (uint32_t)pc); + FAPI_DBG(" D0 : %016llx D1 : %016llx", + (uint64_t)d0, (uint64_t)d1); + FAPI_DBG(" A0 : %04x.%08x A1 : %04x.%08x", + (uint32_t)(a0 >> 32), (uint32_t)a0, + (uint32_t)(a1 >> 32), (uint32_t)a1); + FAPI_DBG(" P0 : %02x P1 : %02x", + (uint8_t)p0, (uint8_t)p1); + FAPI_DBG(" CTR : %06x ETR : %08x.%08x", + (uint32_t)ctr, + (uint32_t)(etr >> 32), (uint32_t)etr); + FAPI_DBG(" SPRG0 : %08x IFR : %016llx", + (uint32_t)sprg0, (uint64_t)ifr); + FAPI_DBG(SEPARATOR); + FAPI_DBG(" IBUF : %08x %08x%08x", + (uint32_t)((state.get(PORE_IBUF_01, reg0), reg0) >> 32), + (uint32_t)(state.get(PORE_IBUF_01, reg1), reg1), + (uint32_t)((state.get(PORE_IBUF_2, reg2), reg2) >> 32)); + FAPI_DBG(" STACK0 : %016llx", + (state.get(PORE_PC_STACK0, reg0), reg0)); + FAPI_DBG(" STACK1 : %016llx", + (state.get(PORE_PC_STACK1, reg0), reg0)); + FAPI_DBG(" STACK2 : %016llx", + (state.get(PORE_PC_STACK2, reg0), reg0)); + FAPI_DBG(SEPARATOR); + FAPI_DBG(" CONTROL : %016llx STATUS : %016llx", + (state.get(PORE_CONTROL, reg0), reg0), + (state.get(PORE_STATUS, reg1), reg1)); + FAPI_DBG(" DBG0 : %016llx DBG1 : %016llx", + (state.get(PORE_DBG0, reg0), reg0), + (state.get(PORE_DBG1, reg1), reg1)); + FAPI_DBG(SEPARATOR); + FAPI_DBG(" TBAR : %04x.%08x EMR : %016llx", + (uint32_t)((state.get(PORE_TABLE_BASE_ADDR, reg0), reg0) >> 32), + (uint32_t)(state.get(PORE_TABLE_BASE_ADDR, reg1), reg1), + (uint64_t)emr); + FAPI_DBG(" MRR : %01x.%08x I2C0 : %016llx", + (uint32_t)((state.get(PORE_MEM_RELOC, reg0), reg0) >> 32), + (uint32_t)(state.get(PORE_MEM_RELOC, reg1), reg1), + (state.get(PORE_I2C_E0_PARAM, reg2), reg2)); + FAPI_DBG(" I2C1 : %016llx I2C2 : %016llx", + (state.get(PORE_I2C_E1_PARAM, reg0), reg0), + (state.get(PORE_I2C_E2_PARAM, reg1), reg1)); + FAPI_DBG(SEPARATOR); + +#undef SEPARATOR +} + + + + diff --git a/src/usr/pore/poreve/porevesrc/pore.H b/src/usr/pore/poreve/porevesrc/pore.H index 7b773d0ad..3a26173e1 100644 --- a/src/usr/pore/poreve/porevesrc/pore.H +++ b/src/usr/pore/poreve/porevesrc/pore.H @@ -1,29 +1,30 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/pore/poreve/porevesrc/pore.H $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2012 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/poreve/porevesrc/pore.H $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ #ifndef __VSBE_PORE_H #define __VSBE_PORE_H -// $Id: pore.H,v 1.14 2011/11/17 19:04:47 jeshua Exp $ +// $Id: pore.H,v 1.15 2012/02/29 20:58:39 bcbrock Exp $ /// \file pore.H /// \brief The implementation of the PoreInterface for the PoreVe environment @@ -46,11 +47,19 @@ namespace vsbe { /// This is the putative tick frequency of the simulation environment, /// used to model the wait() method. +#ifndef __HOSTBOOT_MODULE const double SIMULATOR_TICK_FREQUENCY = 12e9; +#else + const uint64_t SIMULATOR_TICK_FREQUENCY = 12000000000ull; +#endif /// This is the expected operating frequency of the PORE hardware engine, /// used to model the wait() method. +#ifndef __HOSTBOOT_MODULE const double PORE_FREQUENCY = 600e6; +#else + const uint64_t PORE_FREQUENCY = 600000000ull; +#endif }; @@ -223,6 +232,10 @@ public: fapi::ReturnCode getFapiReturnCode(); + /// Dump the state of the engine using FAPI_DBG + void + dump(); + ////////////////////////// Implementation //////////////////////////// diff --git a/src/usr/pore/poreve/porevesrc/poreve.C b/src/usr/pore/poreve/porevesrc/poreve.C index eb2a89ede..9a3576dfd 100644 --- a/src/usr/pore/poreve/porevesrc/poreve.C +++ b/src/usr/pore/poreve/porevesrc/poreve.C @@ -1,26 +1,27 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/pore/poreve/porevesrc/poreve.C $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2012 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END -// $Id: poreve.C,v 1.16 2012/02/27 22:54:15 jeshua Exp $ +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/poreve/porevesrc/poreve.C $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ +// $Id: poreve.C,v 1.24 2012/06/18 23:38:37 bcbrock Exp $ /// \file poreve.C /// \brief The PORE Virtual Environment @@ -38,56 +39,85 @@ using namespace vsbe; PoreVeBase::PoreVeBase(const PoreIbufId i_id, const fapi::Target i_masterTarget) : iv_pore(i_id), - iv_pnorMemory(PNOR_ADDRESS_BYTES), iv_id(i_id), iv_masterTarget(i_masterTarget), iv_slaveTarget(i_masterTarget) { uint32_t porePibBase; + uint8_t pnorI2cAddressBytes; - // Configure the PORE. Only the PIB bus is connected, the OCI bus remains - // unconnected (0). The PIB self-SCOM interface configuration is a - // function of which PORE egine is being configured. Technically we should - // barf if \a i_id is not PORE_SBE or PORE_SLW, but HBI doesn't want any - // throw()s. + do { - if (i_id == PORE_SLW) { - porePibBase = PORE_SLW_PIB_BASE; - } else { - porePibBase = PORE_SBE_PIB_BASE; - } + if (iv_constructorRc) break; - iv_pore.configure(&iv_slaveTarget, &iv_pib, 0, - &iv_dataBuffer, - porePibBase, PORE_PIB_SIZE, - ACCESS_MODE_READ | ACCESS_MODE_WRITE); + // Configure the PORE. Only the PIB bus is connected, the OCI bus + // remains unconnected (0). The PIB self-SCOM interface configuration + // is a function of which PORE egine is being configured. Technically + // we should barf if \a i_id is not PORE_SBE or PORE_SLW, but HBI + // doesn't want any throw()s. - iv_pib.attachPrimarySlave(&iv_pore); + if (i_id == PORE_SLW) { + porePibBase = PORE_SLW_PIB_BASE; + } else { + porePibBase = PORE_SBE_PIB_BASE; + } - // Configure the PNOR controller and attach its memory + iv_pore.configure(&iv_slaveTarget, &iv_pib, 0, + &iv_dataBuffer, + porePibBase, PORE_PIB_SIZE, + ACCESS_MODE_READ | ACCESS_MODE_WRITE); - iv_pnorController.configure(&iv_masterTarget, - &iv_dataBuffer, - PNOR_PIB_BASE, - PNOR_PIB_SIZE, - ACCESS_MODE_READ | ACCESS_MODE_WRITE); + iv_pib.attachPrimarySlave(&iv_pore); - iv_pib.attachPrimarySlave(&iv_pnorController); + // Configure the PNOR controller and configure and attach its memory. + // The PNOR controller PORE I2C configuration will also be saved away + // for use with Centaur targets; See the documentation for + // iv_pnorI2cParam and the code for the reset() method. - iv_pnorController.attachMemory(&iv_pnorMemory, - PNOR_I2C_PORT, - PNOR_I2C_DEVICE_ADDRESS); +#ifdef __USE_POREVE_ATTRIBUTES__ + iv_constructorRc = FAPI_ATTR_GET_(ATTR_PNOR_I2C_ADDRESS_BYTES, + &iv_masterTarget, + pnorI2cAddressBytes); + if (iv_constructorRc) { + FAPI_ERR("Unable to get ATTR_PNOR_I2C_ADDRESS_BYTES"); + break; + } +#else - // Configure the PIB catch-all model + pnorI2cAddressBytes = 4; - iv_pibDefault.configure(&iv_slaveTarget, - &iv_dataBuffer, - PIB_DEFAULT_PIB_BASE, - PIB_DEFAULT_PIB_SIZE, - ACCESS_MODE_READ | ACCESS_MODE_WRITE); +#endif + + iv_pnorController.configure(&iv_masterTarget, + &iv_dataBuffer, + PNOR_PIB_BASE, + PNOR_PIB_SIZE, + ACCESS_MODE_READ | ACCESS_MODE_WRITE); + + iv_pib.attachPrimarySlave(&iv_pnorController); + + iv_pnorMemory.configure(pnorI2cAddressBytes); + + iv_pnorController.attachMemory(&iv_pnorMemory, + PNOR_I2C_PORT, + PNOR_I2C_DEVICE_ADDRESS); - iv_pib.attachSecondarySlave(&iv_pibDefault); + iv_pnorI2cParam.val = 0; + iv_pnorI2cParam.i2c_engine_identifier = (PNOR_PIB_BASE >> 16) & 0xf; + iv_pnorI2cParam.i2c_engine_address_range = 4; + + // Configure the PIB catch-all model + + iv_pibDefault.configure(&iv_slaveTarget, + &iv_dataBuffer, + PIB_DEFAULT_PIB_BASE, + PIB_DEFAULT_PIB_SIZE, + ACCESS_MODE_READ | ACCESS_MODE_WRITE); + + iv_pib.attachSecondarySlave(&iv_pibDefault); + + } while (0); } @@ -96,38 +126,39 @@ PoreVeBase::~PoreVeBase() } -// This is a temporary hack: Until the final specification of the reset state -// of the PORE-SBE engine is available, we initialize the PORE-SBE engine -// here. This is simpler than trying to keep the PMX model up to date as we -// mess with chaging requirements, and it's also better for PMX to assume -// that the PORE-SBE is halted at PMX-IPL, since PMX/Simics is really a model -// for OCC firmware. This initializaton of PORE-SBE is done here rather than -// in the PoreModel because we have the memory address assumptions here. -// -// If this is a PORE-SBE, then the machine comes up running from OTPROM. - -/// \bug Temporary hack - -void +fapi::ReturnCode PoreVeBase::reset(fapi::Target i_slaveTarget) { + fapi::ReturnCode rc; + + HookManager::clearError(); iv_slaveTarget = i_slaveTarget; iv_pore.restart(); - HookManager::clearError(); - if (iv_id == PORE_SBE) { + // If the slave target is Centaur, set up I2C_E0_PARAM to allow the + // Centaur PNOR image to execute. This is only done for Centaur since + // Centaur SBE code is always run virtually. - // The PMX model comes up halted in OCI space. We set the PC to - // OTPROM space and run() 0 instructions. This will clear the stop bit - // to start execution. +#ifdef __USE_POREVE_ATTRIBUTES__ - PoreAddress pc; - uint64_t ran; + /// \bug This does not work yet, but it doesn't hurt (much) to go ahead + /// and initialize the register. - pc.setFromPibAddress(OTPROM_PIB_BASE); - iv_pore.setPc(pc); - iv_pore.run(0, ran); + uint8_t name; + rc = FAPI_ATTR_GET_PRIVILEGED(ATTR_NAME, i_slaveTarget, name); + if (!rc) { + if (name == ENUM_ATTR_NAME_CENTAUR) { + iv_pore.registerWrite(PORE_I2C_E0_PARAM, iv_pnorI2cParam.val); + } } + +#else + + iv_pore.registerWrite(PORE_I2C_E0_PARAM, iv_pnorI2cParam.val); + +#endif + + return rc; } @@ -170,157 +201,245 @@ PoreVeBase::putscom(const uint32_t i_address, const uint64_t i_data, int& o_rc) } +ModelError +PoreVeBase::getmemInteger(const PoreAddress i_address, + uint64_t& o_data, + const size_t i_size) +{ + return iv_pore.getmemInteger(i_address, o_data, i_size); +} + + +ModelError +PoreVeBase::putmemInteger(const PoreAddress i_address, + uint64_t i_data, + const size_t i_size) +{ + return iv_pore.putmemInteger(i_address, i_data, i_size); +} + + +fapi::ReturnCode +PoreVeBase::constructorRc() +{ + return iv_constructorRc; +} + + +fapi::ReturnCode +PoreVeBase::poreRc() +{ + return iv_pore.getFapiReturnCode(); +} + + //////////////////////////////////////////////////////////////////////////// // PoreVe //////////////////////////////////////////////////////////////////////////// PoreVe::PoreVe(const PoreIbufId i_id, - const fapi::Target i_masterTarget) : + const fapi::Target i_masterTarget, + const bool i_useSecondarySeepromConfig) : PoreVeBase(i_id, i_masterTarget), - iv_seepromMemory(SEEPROM_ADDRESS_BYTES) + iv_pibmem(PIBMEM_PIB_SIZE) { uint32_t porePibBase; + uint8_t seepromI2cAddressBytes; + uint8_t seepromI2cDeviceAddress[2]; + uint8_t seepromI2cPort[2]; + int seepromConfig; - // Reconfigure the Pore - this doesn't hurt anything in the previous - // configuration in the base class as this is a set of simple pointer and - // data assignments. But it's another reason to jettison the requirement - // for the base class. The PORE was attached to the PIB in the base - // class. + do { - if (i_id == PORE_SLW) { - porePibBase = PORE_SLW_PIB_BASE; - } else { - porePibBase = PORE_SBE_PIB_BASE; - } + // Reconfigure the Pore - this doesn't hurt anything in the previous + // configuration in the base class as this is a set of simple pointer + // and data assignments. But it's another reason to jettison the + // requirement for the base class. The PORE was attached to the PIB + // in the base class. - iv_pore.configure(&iv_slaveTarget, &iv_pib, &iv_oci, - &iv_dataBuffer, - porePibBase, PORE_PIB_SIZE, - ACCESS_MODE_READ | ACCESS_MODE_WRITE); + if (i_id == PORE_SLW) { + porePibBase = PORE_SLW_PIB_BASE; + } else { + porePibBase = PORE_SBE_PIB_BASE; + } - // Configure the OTPROM + iv_pore.configure(&iv_slaveTarget, &iv_pib, &iv_oci, + &iv_dataBuffer, + porePibBase, PORE_PIB_SIZE, + ACCESS_MODE_READ | ACCESS_MODE_WRITE); - iv_otprom.configure(&iv_slaveTarget, - &iv_dataBuffer, - OTPROM_PIB_BASE, - OTPROM_PIB_SIZE, - ACCESS_MODE_READ | ACCESS_MODE_EXECUTE, - &iv_otpromMemory); + // Configure the OTPROM - iv_pib.attachPrimarySlave(&iv_otprom); + iv_otprom.configure(&iv_slaveTarget, + &iv_dataBuffer, + OTPROM_PIB_BASE, + OTPROM_PIB_SIZE, + ACCESS_MODE_READ | ACCESS_MODE_EXECUTE, + &iv_otpromMemory); + iv_pib.attachPrimarySlave(&iv_otprom); - // Configure the PIBMEM - iv_pibmem.configure(&iv_slaveTarget, - &iv_dataBuffer, - PIBMEM_PIB_BASE, - PIBMEM_PIB_SIZE, - ACCESS_MODE_READ | - ACCESS_MODE_WRITE | - ACCESS_MODE_EXECUTE, - &iv_pibmemMemory); + // Configure the PIBMEM. Unlike the other memories that represent + // pre-programmed ROM memories, the PIBMEM is an uninitialized RAM, and + // arguably we could allocate a blank image for it here. However for + // consistency (and ease of checkpointing) we require the user to + // explicitly provide and map a PIBMEM image, which should be of size + // (PIBMEM_PIB_REGISTERS * 8) bytes. - iv_pib.attachPrimarySlave(&iv_pibmem); + iv_pibmem.configure(&iv_slaveTarget, + &iv_dataBuffer, + PIBMEM_PIB_BASE, + PIBMEM_PIB_SIZE, + ACCESS_MODE_READ | + ACCESS_MODE_WRITE | + ACCESS_MODE_EXECUTE, + &iv_pibmemMemory); + iv_pib.attachPrimarySlave(&iv_pibmem); - // Configure the SEEPROM controller - iv_seepromController.configure(&iv_slaveTarget, - &iv_dataBuffer, - SEEPROM_PIB_BASE, - SEEPROM_PIB_SIZE, - ACCESS_MODE_READ | ACCESS_MODE_WRITE); + // Configure the SEEPROM controller and its memory - iv_pib.attachPrimarySlave(&iv_seepromController); + seepromConfig = (i_useSecondarySeepromConfig ? 1 : 0); - iv_seepromController.attachMemory(&iv_seepromMemory, - SEEPROM_I2C_PORT, - SEEPROM_I2C_DEVICE_ADDRESS); +#ifdef __USE_POREVE_ATTRIBUTES__ - // Configure Mainstore + iv_constructorRc = FAPI_ATTR_GET(ATTR_SEEPROM_I2C_ADDRESS_BYTES, + &iv_masterTarget, + seepromI2cAddressBytes); + if (iv_constructorRc) { + FAPI_ERR("Unable to get ATTR_SEEPROM_I2C_ADDRESS_BYTES"); + break; + } - iv_main.configure(&iv_slaveTarget, - &iv_dataBuffer, - MAINSTORE_OCI_BASE, - MAINSTORE_OCI_SIZE, - ACCESS_MODE_READ | ACCESS_MODE_WRITE, - &iv_mainMemory); - - iv_oci.attachPrimarySlave(&iv_main); + iv_constructorRc = FAPI_ATTR_GET(ATTR_SEEPROM_I2C_DEVICE_ADDRESS, + &iv_masterTarget, + seepromI2cDeviceAddtess); + if (iv_constructorRc) { + FAPI_ERR("Unable to get ATTR_SEEPROM_I2C_DEVICE_ADDRESS"); + break; + } - // Configure SRAM + iv_constructorRc = FAPI_ATTR_GET(ATTR_SEEPROM_I2C_PORT, + &iv_masterTarget, + seepromI2cPort); + if (iv_constructorRc) { + FAPI_ERR("Unable to get ATTR_SEEPROM_I2C_PORT"); + break; + } - iv_sram.configure(&iv_slaveTarget, - &iv_dataBuffer, - SRAM_OCI_BASE, - SRAM_OCI_SIZE, - ACCESS_MODE_READ | ACCESS_MODE_WRITE, - &iv_sramMemory); +#else - iv_oci.attachPrimarySlave(&iv_sram); + seepromI2cAddressBytes = 2; // Murano primary configuration + seepromI2cDeviceAddress[0] = 0x56; + seepromI2cPort[0] = 0; +#endif -#ifdef PM_HACKS - // This device provides write-only access to a single control register in - // the PMC. + iv_seepromController.configure(&iv_slaveTarget, + &iv_dataBuffer, + SEEPROM_PIB_BASE, + SEEPROM_PIB_SIZE, + ACCESS_MODE_READ | ACCESS_MODE_WRITE); - iv_pmc.configure(&iv_slaveTarget, - &iv_dataBuffer, - PMC_OCI_BASE, - PMC_OCI_SIZE, - ACCESS_MODE_WRITE); + iv_pib.attachPrimarySlave(&iv_seepromController); - iv_oci.attachPrimarySlave(&iv_pmc); -#endif // PM_HACKS + iv_seepromMemory.configure(seepromI2cAddressBytes); + // printf("ATTACHING MEMORY\n"); - // Configure the Pib2Cfam component to remap MBOX scom addresses to cfam addresses - uint8_t fsi_gpreg_scom_access; - fapi::ReturnCode frc; + iv_seepromController. + attachMemory(&iv_seepromMemory, + seepromI2cPort[seepromConfig], + seepromI2cDeviceAddress[seepromConfig]); - //JDS TODO - uncomment this when the model actually works -// frc = FAPI_ATTR_GET( ATTR_FSI_GP_REG_SCOM_ACCESS, &iv_slaveTarget, fsi_gpreg_scom_access ); - fsi_gpreg_scom_access = 0; + // Configure Mainstore - if(!frc.ok()) { - FAPI_ERR( "Unable to get ATTR_FSI_GP_REG_SCOM_ACCESS for target\n" ); - //JDS TODO - create an actual fapi error - // FAPI_SET_HWP_ERROR( frc, "Unable to get ATTR_FSI_GP_REG_SCOM_ACCESS for target\n" ); - } - if( !fsi_gpreg_scom_access ) { - iv_pib2Cfam.configure(&iv_slaveTarget, - &iv_dataBuffer, - PIB2CFAM_PIB_BASE, - PIB2CFAM_PIB_SIZE, - ACCESS_MODE_READ | ACCESS_MODE_WRITE); + iv_main.configure(&iv_slaveTarget, + &iv_dataBuffer, + MAINSTORE_OCI_BASE, + MAINSTORE_OCI_SIZE, + ACCESS_MODE_READ | ACCESS_MODE_WRITE, + &iv_mainMemory); + + iv_oci.attachPrimarySlave(&iv_main); - iv_pib.attachPrimarySlave(&iv_pib2Cfam); - } - // Configure the sbeVital register emulation - uint8_t use_hw_sbe_vital_register; + // Configure SRAM - // JDS TODO - this needs to be done with an attribute (ATTR_USE_HW_SBE_VITAL_REGISTER requested) -// frc = FAPI_ATTR_GET( ATTR_USE_HW_SBE_VITAL_REGISTER, &iv_slaveTarget, use_hw_sbe_vital_register ); -// if(!frc.ok()) { -// FAPI_ERR( "Unable to get ATTR_USE_HW_SBE_VITAL_REGISTER for target\n" ); -// //JDS TODO - create an actual fapi error -// // FAPI_SET_HWP_ERROR( frc, "Unable to get ATTR_USE_HW_SBE_VITAL_REGISTER for target\n" ); -// } - use_hw_sbe_vital_register = 0; //JDS TODO - TMP until the attribute is supported and the hardware allows access to the register + iv_sram.configure(&iv_slaveTarget, + &iv_dataBuffer, + SRAM_OCI_BASE, + SRAM_OCI_SIZE, + ACCESS_MODE_READ | ACCESS_MODE_WRITE, + &iv_sramMemory); - if( !use_hw_sbe_vital_register ) { - iv_sbeVital.configure(&iv_slaveTarget, - &iv_dataBuffer, - SBEVITAL_PIB_BASE, - SBEVITAL_PIB_SIZE, - ACCESS_MODE_READ | ACCESS_MODE_WRITE); + iv_oci.attachPrimarySlave(&iv_sram); - iv_pib.attachPrimarySlave(&iv_sbeVital); - } +#ifdef PM_HACKS + // This device provides write-only access to a single control register + // in the PMC. + + iv_pmc.configure(&iv_slaveTarget, + &iv_dataBuffer, + PMC_OCI_BASE, + PMC_OCI_SIZE, + ACCESS_MODE_WRITE); + + iv_oci.attachPrimarySlave(&iv_pmc); +#endif // PM_HACKS + + // Note: Optional components are always present in the model and + // always configured, but may not be attached to the busses. This + // simpifies certain types of testing. + + // Configure the Pib2Cfam component to remap MBOX scom addresses to + // cfam addresses. + uint8_t fsi_gpreg_scom_access; + + iv_constructorRc = FAPI_ATTR_GET( ATTR_FSI_GP_REG_SCOM_ACCESS, + &iv_masterTarget, + fsi_gpreg_scom_access); + if (iv_constructorRc) { + FAPI_ERR( "Unable to get ATTR_FSI_GP_REG_SCOM_ACCESS for target\n" ); + break; + } + + iv_pib2Cfam.configure(&iv_slaveTarget, + &iv_dataBuffer, + PIB2CFAM_PIB_BASE, + PIB2CFAM_PIB_SIZE, + ACCESS_MODE_READ | ACCESS_MODE_WRITE); + + if( !fsi_gpreg_scom_access ) { + iv_pib.attachPrimarySlave(&iv_pib2Cfam); + } + + // Configure the sbeVital register emulation + uint8_t use_hw_sbe_vital_register; + + iv_constructorRc = FAPI_ATTR_GET( ATTR_CHIP_HAS_SBE, + &iv_masterTarget, + use_hw_sbe_vital_register ); + if (iv_constructorRc) { + FAPI_ERR( "Unable to get ATTR_CHIP_HAS_SBE for target\n" ); + break; + } + + iv_sbeVital.configure(&iv_slaveTarget, + &iv_dataBuffer, + SBEVITAL_PIB_BASE, + SBEVITAL_PIB_SIZE, + ACCESS_MODE_READ | ACCESS_MODE_WRITE); + + if( !use_hw_sbe_vital_register ) { + iv_pib.attachPrimarySlave(&iv_sbeVital); + } + + } while (0); } diff --git a/src/usr/pore/poreve/porevesrc/poreve.H b/src/usr/pore/poreve/porevesrc/poreve.H index 41c64e7e0..387fa6604 100644 --- a/src/usr/pore/poreve/porevesrc/poreve.H +++ b/src/usr/pore/poreve/porevesrc/poreve.H @@ -1,29 +1,30 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/pore/poreve/porevesrc/poreve.H $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2012 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/poreve/porevesrc/poreve.H $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ #ifndef __VSBE_POREVE_H #define __VSBE_POREVE_H -// $Id: poreve.H,v 1.20 2012/02/27 22:50:53 jeshua Exp $ +// $Id: poreve.H,v 1.25 2012/06/18 23:38:37 bcbrock Exp $ /// \file poreve.H /// \brief The PORE Virtual Environment @@ -73,7 +74,9 @@ #include "fapi.H" #include "fasti2c.H" +#include "pibmem.H" #include "poremodel.H" +#include "poreregister.H" #include "pore.H" #include "pib2cfam.H" @@ -140,9 +143,9 @@ namespace vsbe { /// The number of PIB \e registers defined by the PIBMEM memory controller /// /// PIB memories are 8-byte \e word addressed. The maximum amount of - /// memory accessible through the controller is (PIBMEM_PIB_SIZE * 8) + /// memory accessible through the controller is (PIBMEM_PIB_REGISTERS * 8) /// bytes (3KB). - const uint64_t PIBMEM_PIB_SIZE = 0x180; + const uint64_t PIBMEM_PIB_REGISTERS = 0x180; ////////////////////////////////////////////////////////////////////// @@ -155,11 +158,12 @@ namespace vsbe { /// The number of registers defined by the PNOR memory controller const size_t PNOR_PIB_SIZE = LPCM_REGISTERS; - /// The number of bytes in a PNOR address (actually a parameter of the - /// memory attached to the controller) - const size_t PNOR_ADDRESS_BYTES = 4; - /// The PNOR I2C Port Number + /// + /// When the ECCAX unit is configured for access to the LPC (PNOR) + /// interface, the I2C port and I2C device address are ignored by the + /// unit, however we go ahead and define these constants as 0 for the + /// benefit of our generic I2C controller model. const unsigned PNOR_I2C_PORT = 0; /// The PNOR I2C Device Address @@ -176,18 +180,6 @@ namespace vsbe { /// The number of registers defined by the SEEPROM memory controller const uint64_t SEEPROM_PIB_SIZE = FASTI2C_REGISTERS; - /// The number of bytes in an SEEPROM address - const uint64_t SEEPROM_ADDRESS_BYTES = 2; - - /// The SEEPROM I2C Port Number - const unsigned SEEPROM_I2C_PORT = 0; - - /// The SEEPROM I2C Device Address - /// - /// \bug This value (0) is bogus, need the real value from the system - /// design. - const unsigned SEEPROM_I2C_DEVICE_ADDRESS = 0; - ////////////////////////////////////////////////////////////////////// // PIB Default Catch-All Model @@ -271,15 +263,28 @@ public: //////////////////// Simulation Interface ///////////////////////// - /// Reset the simulation to target a new slave + /// Reset the simulation and target a new slave /// /// \param[in] i_slaveTarget The slave target of the new slave /// - /// The reset() method is provided to cleanly reset the simulation for - /// simulation with a new slave target. Once reset, the application is - /// responsible for setting up the register state of the Pore and invoking - /// the run() method to begin simulation. - virtual void + /// The reset() method is provided to cleanly reset the simulator for + /// simulation with a new slave target. + /// + /// If the embedded PORE engine is PORE-SBE, then this method simulates + /// the auto-POR sequence for the engine, and the engine comes up with a + /// 'running' status at the correct auto-POR branch table address. For + /// other engines the application is responsible for setting up the + /// register state of the Pore and invoking the run() method to begin + /// simulation. As a side effect, any error status is also cleared from + /// the HookManager. + /// + /// If the slave target is Centaur, then this method also takes the step + /// of initializing the I2C_E0_PARAM register to allow the Centaur "PNOR" + /// image to access the virtual PNOR. + /// + /// \returns The return code from the call of FAPI_ATTR_GET_PRIVILEGED() + /// used to determine the target type. + virtual fapi::ReturnCode reset(fapi::Target i_slaveTarget); @@ -306,6 +311,9 @@ public: /// model return modeled results, and accesses of non-modeled addresses /// are converted into FAPI calls. /// + /// \note Use the getmemInteger() method to read from OCI/I2C memory + /// spaces. + /// /// \returns A return value of 0 indicates success of the method call, but /// does not guarantee that the PIB transaction succeeded. It will also be /// necessary to also observe that PIB/PCB return code \a o_rc was @@ -330,6 +338,9 @@ public: /// model update modeled registers, and accesses of non-modeled addresses /// are converted into FAPI calls. /// + /// \note Use the putmemInteger() method to write to OCI/I2C memory + /// spaces. + /// /// \returns A return value of 0 indicates success of the method call, but /// does not guarantee that the PIB transaction succeeded. It will also be /// necessary to also observe that PIB/PCB return code \a o_rc was @@ -338,6 +349,39 @@ public: virtual ModelError putscom(const uint32_t i_address, const uint64_t i_data, int& o_rc); + + /// See PoreModel::getmemInteger() + virtual ModelError + getmemInteger(const PoreAddress i_address, + uint64_t& o_data, + const size_t i_size); + + + /// See PoreModel::putmemInteger() + virtual ModelError + putmemInteger(const PoreAddress i_address, + uint64_t i_data, + const size_t i_size); + + + /// Return the FAPI return code associated with constructing the PoreVe + /// object. + /// + /// Any application constucting a PoreVe object must check that the object + /// was constructed without error by using this method. + virtual fapi::ReturnCode + constructorRc(); + + + /// Return the last FAPI return code from any PORE operations in the + /// virtual environment. + /// + /// If the status returned by run() includes the bit + /// PORE_STATUS_MODEL_ERROR, then calling poreRc() will return the FAPI + /// return code associated with the error, if any. + virtual fapi::ReturnCode + poreRc(); + //////////////////// Public Implementation //////////////////////////// @@ -399,6 +443,27 @@ protected: /// this data member is provided to all slaves during configuration. ecmdDataBufferBase iv_dataBuffer; + /// The FAPI return code associated with object construction + /// + /// Constructing a PoreVe object entails making FAPI and other API calls + /// that may fail, however the host boot environment does not support + /// exceptions, only FAPI return codes. To the extent possible, the + /// constructor is coded such that this member holds the first non-OK + /// return code encountered during construction, if any. Any application + /// constucting a PoreVe object must check that the object was constructed + /// without error by using the constructorRc() method. + fapi::ReturnCode iv_constructorRc; + + /// The I2C setup for the PNOR controller + /// + /// When the PoreVe-SBE is being used to bring up the Centaur, this data + /// member holds the I2C parameters required to allow the SBE to access + /// the virtual PNOR containing the Centaur IPL code. For processor IPL + /// the IPL code itself does all setup, but since Centaur is only brought + /// up virtually we elected to do this one piece of setup behind the + /// scenes in the reset() method. + pore_i2c_en_param_reg iv_pnorI2cParam; + ///////////////////////////// Safety ////////////////////////////////// @@ -437,7 +502,15 @@ public: /// \param[in] i_masterTarget The fapi::Target associated with the master /// chip in an HBI master/slave configuration. This target is also /// installed into \a iv_slaveTarget by the constructor. - PoreVe(const PoreIbufId i_id, const fapi::Target i_masterTarget); + /// + /// \param[in] i_useSecondarySeepromConfig The model contains a single + /// SEEPROM memory, however the hardware always includes a primary and + /// secondary SEEPROM. This option to the constructor selects which + /// SEEPROM addressing attributes (device Id, port) to use for the SEEPROM + /// memory model. The default is to use the primary attributes. + PoreVe(const PoreIbufId i_id, + const fapi::Target i_masterTarget, + const bool i_useSecondarySeepromConfig = false); virtual ~PoreVe(); @@ -470,10 +543,10 @@ public: /// The OTPROM memory model Memory iv_otpromMemory; - /// The PIBMEM controller model - No advanced functions implemented for now - PibMemory iv_pibmem; + /// The PIBMEM controller model + Pibmem iv_pibmem; - /// The PIPMEM memory model + /// The PIBMEM memory model Memory iv_pibmemMemory; /// The SEEPROM controller model diff --git a/src/usr/pore/poreve/porevesrc/sbevital.C b/src/usr/pore/poreve/porevesrc/sbevital.C index d8e09a29c..e5ece8ec6 100644 --- a/src/usr/pore/poreve/porevesrc/sbevital.C +++ b/src/usr/pore/poreve/porevesrc/sbevital.C @@ -1,25 +1,26 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/pore/poreve/porevesrc/sbevital.C $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2012 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/pore/poreve/porevesrc/sbevital.C $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ // -*- mode: C++; c-file-style: "linux"; -*- // $Id: sbevital.C,v 1.3 2012/02/27 22:51:37 jeshua Exp $ @@ -49,7 +50,7 @@ SbeVital::~SbeVital() fapi::ReturnCode SbeVital::operation(Transaction& io_transaction) { - fapi::ReturnCode rc=(fapi::ReturnCodes)0; + fapi::ReturnCode rc; ModelError me; //On a scom write, put the data into the register diff --git a/src/usr/pore/test/poretest.H b/src/usr/pore/test/poretest.H index 233fabb21..bd7c3c1c8 100644 --- a/src/usr/pore/test/poretest.H +++ b/src/usr/pore/test/poretest.H @@ -30,225 +30,27 @@ * @brief Test case for POREVE code */ -#include <list> +#include <vector> #include <cxxtest/TestSuite.H> #include <targeting/common/commontargeting.H> #include <fapiPoreVeArg.H> #include <fapiTarget.H> #include <fapi.H> +#include <fapiPlatHwpInvoker.H> #include <vfs/vfs.H> +#include <errl/errlmanager.H> -//@todo - These two include files are to workaround -//1. Avoid running test case in VBU -//2. To call isSlavePresent(). Need to be removed when PD works. -#include <fsi/fsiif.H> - -#define CENTAUR_SBE_PNOR_MRR 0 // Memory Relocation Register for Centaur +#define CENTAUR_SBE_PNOR_MRR 0 // Memory Relocation Register for Centaur using namespace TARGETING; using namespace vsbe; extern fapi::ReturnCode fapiPoreVe(const fapi::Target i_target, - std::list<uint64_t> & io_sharedObjectArgs); + std::vector<FapiPoreVeArg *> & io_sharedObjectArgs); class PoreTest: public CxxTest::TestSuite { public: - /** - * @brief PORE test #1 - * Run a sample procedure on Centaur - */ - void testPore1(void) - { - fapi::ReturnCode l_rc = fapi::FAPI_RC_SUCCESS; - fapi::ReturnCode l_rc2 = fapi::FAPI_RC_SUCCESS; - bool l_unloadSbePnorImg = false; - size_t l_sbePnorSize = 0; - const char * l_sbePnorAddr = NULL; - errlHndl_t l_errl = NULL; - - do - { - // Loading sbe_pnor img - l_errl = VFS::module_load("centaur.sbe_pnor.bin"); - if (l_errl) - { - TS_FAIL("testPore1: Error loading centaur.sbe_pnor.bin!"); - break; - } - else - { - // Set flag to unload - l_unloadSbePnorImg = true; - l_errl = VFS::module_address("centaur.sbe_pnor.bin", l_sbePnorAddr, l_sbePnorSize); - if(l_errl) - { - TS_FAIL("testPore1: Error getting load address of centaur.sbe_pnor.bin!"); - break; - } - else - { - char l_header[10]; - memcpy (l_header, l_sbePnorAddr, 9); - l_header[9] = '\0'; - FAPI_INF("testPore1:Loading centaur.sbe_pnor.bin, Addr 0x%llX, Size %d, Header %s", - l_sbePnorAddr, l_sbePnorSize, l_header); - } - } - - // ------------ Setup Centaur targets ------------------- - // Use PredicateIsFunctional to filter only functional chips - TARGETING::PredicateIsFunctional l_isFunctional; - // filter for functional Centaur Chips - TARGETING::PredicateCTM l_membufChipFilter(CLASS_CHIP, TYPE_MEMBUF); - // Declare a postfix expression widget - TARGETING::PredicatePostfixExpr l_functionalAndMembufChipFilter; - // is-a-membuf-chip is-functional AND - l_functionalAndMembufChipFilter.push(&l_membufChipFilter).push(&l_isFunctional).And(); - // loop through all the targets, applying the filter, and put the results in l_pMemBufs - TARGETING::TargetRangeFilter l_pMemBufs( - TARGETING::targetService().begin(), - TARGETING::targetService().end(), - &l_functionalAndMembufChipFilter ); - - // ------------- Setup POREVE arguments ----------------- - // Setup args - std::list<uint64_t> myArgs; - - // Set FapiPoreVeOtherArg: run unlimited instructions - FapiPoreVeOtherArg *l_otherArg = - new FapiPoreVeOtherArg(vsbe::RUN_UNLIMITED, - vsbe::PORE_SBE); - // Entry point - l_otherArg->iv_entryPoint = const_cast<char*>("pnor::_sbe_pnor_start"); - l_otherArg->iv_mrr = CENTAUR_SBE_PNOR_MRR; - uint64_t fapiArg = reinterpret_cast<uint64_t> (l_otherArg); - myArgs.push_back(fapiArg); - - // Set FapiPoreVeMemArg for pnor option, base address = 0 - uint32_t base_addr = 0; - char* l_dataPnor = const_cast<char*>(l_sbePnorAddr); - FapiPoreVeMemArg* l_memArg = new FapiPoreVeMemArg(ARG_PNOR, - base_addr, l_sbePnorSize, - static_cast<void*>(l_dataPnor)); - fapiArg = reinterpret_cast<uint64_t> (l_memArg); - myArgs.push_back(fapiArg); - - // Create state argument to dump out state for debugging purpose - FapiPoreVeStateArg *l_stateArg = new FapiPoreVeStateArg(NULL); - l_stateArg->iv_installState = false; - l_stateArg->iv_extractState = true; - fapiArg = reinterpret_cast<uint64_t> (l_stateArg); - myArgs.push_back(fapiArg); - - - // Run loop on all Centaurs - for ( ; l_pMemBufs; ++l_pMemBufs ) - { - // Create a FAPI Target - const TARGETING::Target* l_membuf_target = *l_pMemBufs; - const fapi::Target l_fapiTarget( - fapi::TARGET_TYPE_MEMBUF_CHIP, - reinterpret_cast<void *> - (const_cast<TARGETING::Target*>(l_membuf_target))); - - // Put out info on target - FAPI_INF("testPore1: Running cen_sbe_tp_chiplet_init1 on Centaur entity path..."); - EntityPath l_path; - l_path = l_membuf_target->getAttr<ATTR_PHYS_PATH>(); - l_path.dump(); - - //@todo - Make sure target is present - // Temporary hack until PD works - if ( !FSI::isSlavePresent(l_membuf_target) ) - { - FAPI_INF("testPore1: Skip this Centaur because it's not present"); - continue; - } - - // Run the engine - FAPI_INF("testPore1: Start VSBE engine..."); - //@todo - //@VBU workaround - Do not run in VPO since it takes too long - //Temporarily disable this test case in VBU because it takes too long to run. - //Also, the image used for Centaur is only a temporary image provided by Todd to try out. - //When we have an official Centaur sbe_pnor image, use it to create a simple one to run - //test case. - if ( !TARGETING::is_vpo() ) - { - // @todo - Must comment out for now because Todd's image will fail test case - // l_rc = fapiPoreVe(l_fapiTarget, myArgs); - } - - if (l_rc != fapi::FAPI_RC_SUCCESS) - { - uint32_t val = l_rc; - FAPI_INF("testPore1: Error returned from VSBE engine on this Centaur, l_rc 0x%llX", - val); - break; - } - else - { - FAPI_INF("testPore1: VSBE engine runs successfully on this Centaur"); - } - - // @todo - For now, run only on 1 Centaur to save VPO time - break; - - - } // end for l_pMemBufs - - - // Freeing memory - if (l_otherArg) - { - delete l_otherArg; - l_otherArg = NULL; - } - - if (l_memArg) - { - delete l_memArg; - l_memArg = NULL; - } - - if (l_stateArg) - { - delete l_stateArg; - l_stateArg = NULL; - } - - - - } while(0); - - // Unload sbe_pnor - if (l_unloadSbePnorImg == true) - { - l_rc2 = fapiUnloadInitFile("centaur.sbe_pnor.bin", l_sbePnorAddr, - l_sbePnorSize); - if (l_rc2 != fapi::FAPI_RC_SUCCESS) - { - FAPI_ERR("testPore1: Error unloading centaur.sbe_pnor.bin"); - if (l_rc == fapi::FAPI_RC_SUCCESS) - { - l_rc = l_rc2; - } - } - } - - // Test fail/pass - if (l_rc != fapi::FAPI_RC_SUCCESS) - { - TS_FAIL("testPore1 fails! Check FAPI trace"); - } - else - { - TS_TRACE("testPore1 ran successfully!"); - } - - return; - } /** * @brief PORE test #2 |