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/poreve | |
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/poreve')
32 files changed, 2835 insertions, 1158 deletions
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 |