summaryrefslogtreecommitdiffstats
path: root/src/usr/pore/poreve
diff options
context:
space:
mode:
authorVan Lee <vanlee@us.ibm.com>2012-06-27 23:12:29 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2012-07-12 09:54:20 -0500
commit8de05d745201752e69c646e2586122b5cf89b48d (patch)
tree5dddc2e2ad6f5c662708eb72481b170ec683a694 /src/usr/pore/poreve
parent53cc1854646f8e1b82cf94f3beec8f36ef7cd353 (diff)
downloadtalos-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')
-rw-r--r--src/usr/pore/poreve/makefile13
-rw-r--r--src/usr/pore/poreve/model/bebits.H46
-rw-r--r--src/usr/pore/poreve/model/modelerror.H51
-rw-r--r--src/usr/pore/poreve/model/poreaddress.C48
-rw-r--r--src/usr/pore/poreve/model/poreinterface.C71
-rw-r--r--src/usr/pore/poreve/model/poreinterface.H59
-rw-r--r--src/usr/pore/poreve/model/poremodel.C275
-rw-r--r--src/usr/pore/poreve/model/poremodel.H124
-rw-r--r--src/usr/pore/poreve/model/poreregister.H90
-rw-r--r--src/usr/pore/poreve/pore_model/ibuf/pore_ibuf.h51
-rw-r--r--src/usr/pore/poreve/pore_model/ibuf/pore_inline_decode.c49
-rw-r--r--src/usr/pore/poreve/pore_model/ibuf/pore_inline_decode.h49
-rw-r--r--src/usr/pore/poreve/pore_model/ibuf/pore_model.c257
-rw-r--r--src/usr/pore/poreve/pore_model/ibuf/pore_regs.h84
-rw-r--r--src/usr/pore/poreve/pore_model/include/pore_model.h47
-rw-r--r--src/usr/pore/poreve/pore_model/include/pore_wrap.h46
-rw-r--r--src/usr/pore/poreve/porevesrc/bus.C531
-rw-r--r--src/usr/pore/poreve/porevesrc/bus.H47
-rw-r--r--src/usr/pore/poreve/porevesrc/dbg.C108
-rw-r--r--src/usr/pore/poreve/porevesrc/dbg.H115
-rw-r--r--src/usr/pore/poreve/porevesrc/fasti2c.C70
-rw-r--r--src/usr/pore/poreve/porevesrc/fasti2c.H65
-rw-r--r--src/usr/pore/poreve/porevesrc/hookmanager.C61
-rw-r--r--src/usr/pore/poreve/porevesrc/hookmanager.H77
-rw-r--r--src/usr/pore/poreve/porevesrc/pib2cfam.C64
-rw-r--r--src/usr/pore/poreve/porevesrc/pibmem.C314
-rw-r--r--src/usr/pore/poreve/porevesrc/pibmem.H239
-rw-r--r--src/usr/pore/poreve/porevesrc/pore.C168
-rw-r--r--src/usr/pore/poreve/porevesrc/pore.H59
-rw-r--r--src/usr/pore/poreve/porevesrc/poreve.C493
-rw-r--r--src/usr/pore/poreve/porevesrc/poreve.H175
-rw-r--r--src/usr/pore/poreve/porevesrc/sbevital.C47
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
OpenPOWER on IntegriCloud