summaryrefslogtreecommitdiffstats
path: root/src/usr
diff options
context:
space:
mode:
authorAdam Muhle <armuhle@us.ibm.com>2011-07-26 09:57:45 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2011-08-03 08:12:22 -0500
commit5867b512c1592fce1a5bab56e4320efd6598645f (patch)
treedc0e33872419bd649b8015b04c4272fbaedd72b8 /src/usr
parent937c177a8f2decfc05aa4c36788cb14a84631b05 (diff)
downloadtalos-hostboot-5867b512c1592fce1a5bab56e4320efd6598645f.tar.gz
talos-hostboot-5867b512c1592fce1a5bab56e4320efd6598645f.zip
Adding fake PNOR Device Driver Support
Change-Id: Ic434159183bc4dd91c8ba588730cda7e0766c6c0 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/223 Tested-by: Jenkins Server Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr')
-rw-r--r--src/usr/cxxtest/cxxtestexec.C2
-rw-r--r--src/usr/pnor/makefile2
-rw-r--r--src/usr/pnor/pnordd.C301
-rw-r--r--src/usr/pnor/pnordd.H98
-rw-r--r--src/usr/pnor/test/makefile2
-rw-r--r--src/usr/pnor/test/pnorddtest.H130
6 files changed, 533 insertions, 2 deletions
diff --git a/src/usr/cxxtest/cxxtestexec.C b/src/usr/cxxtest/cxxtestexec.C
index 5470b718a..63a12c7ca 100644
--- a/src/usr/cxxtest/cxxtestexec.C
+++ b/src/usr/cxxtest/cxxtestexec.C
@@ -117,6 +117,8 @@ void _start(void *io_pArgs)
tidrc = task_exec( vfsItr->module, NULL );
TRACDCOMP( g_trac_cxxtest, "Launched task: tidrc=%d",
tidrc );
+ //@fixme-try to alleviate cxxtest deadlock
+ nanosleep( 1, 0 ); //sleep 1 second
}
}
diff --git a/src/usr/pnor/makefile b/src/usr/pnor/makefile
index d52765cd1..0700f7554 100644
--- a/src/usr/pnor/makefile
+++ b/src/usr/pnor/makefile
@@ -1,7 +1,7 @@
ROOTPATH = ../../..
MODULE = pnor
-OBJS = pnorrp.o
+OBJS = pnorrp.o pnordd.o
SUBDIRS = test.d
diff --git a/src/usr/pnor/pnordd.C b/src/usr/pnor/pnordd.C
new file mode 100644
index 000000000..fe4699fbe
--- /dev/null
+++ b/src/usr/pnor/pnordd.C
@@ -0,0 +1,301 @@
+/**
+ * @file pnordd.C
+ *
+ * @brief Implementation of the PNOR Device Driver
+ */
+
+/*****************************************************************************/
+// I n c l u d e s
+/*****************************************************************************/
+#include <sys/mmio.h>
+#include <sys/task.h>
+#include <sys/sync.h>
+#include <string.h>
+#include <devicefw/driverif.H>
+#include <trace/interface.H>
+#include <errl/errlentry.H>
+#include <targeting/targetservice.H>
+#include <errl/errlmanager.H>
+#include "pnordd.H"
+#include <pnor/pnorif.H>
+
+#define FAKE_PNOR_START 7*1024*1024
+#define FAKE_PNOR_END 8*1024*1024
+
+
+extern trace_desc_t* g_trac_pnor;
+
+namespace PNOR
+{
+
+
+
+/**
+ * @brief Performs an PNOR Read Operation
+ * This function performs a PNOR Read operation. It follows a pre-defined
+ * prototype functions in order to be registered with the device-driver
+ * framework.
+ *
+ * @param[in] i_opType Operation type, see DeviceFW::OperationType
+ * in driverif.H
+ * @param[in] i_target PNOR target
+ * @param[in/out] io_buffer Read: Pointer to output data storage
+ * Write: Pointer to input data storage
+ * @param[in/out] io_buflen Input: size of io_buffer (in bytes)
+ * Output:
+ * Read: Size of output data
+ * Write: Size of data written
+ * @param[in] i_accessType DeviceFW::AccessType enum (usrif.H)
+ * @param[in] i_args This is an argument list for DD framework.
+ * In this function, there's only one argument,
+ * containing the PNOR address and chip select
+ * @return errlHndl_t
+ */
+errlHndl_t ddRead(DeviceFW::OperationType i_opType,
+ TARGETING::Target* i_target,
+ void* io_buffer,
+ size_t& io_buflen,
+ int64_t i_accessType,
+ va_list i_args)
+{
+ errlHndl_t l_err = NULL;
+ uint64_t l_addr = va_arg(i_args,uint64_t);
+
+ do{
+ l_err = Singleton<PnorDD>::instance().read(io_buffer,
+ io_buflen,
+ l_addr);
+ if(l_err)
+ {
+ break;
+ }
+
+ }while(0);
+
+ return l_err;
+}
+
+/**
+ * @brief Performs an PNOR Write Operation
+ * This function performs a PNOR Write operation. It follows a pre-defined
+ * prototype functions in order to be registered with the device-driver
+ * framework.
+ *
+ * @param[in] i_opType Operation type, see DeviceFW::OperationType
+ * in driverif.H
+ * @param[in] i_target PNOR target
+ * @param[in/out] io_buffer Read: Pointer to output data storage
+ * Write: Pointer to input data storage
+ * @param[in/out] io_buflen Input: size of io_buffer (in bytes)
+ * Output:
+ * Read: Size of output data
+ * Write: Size of data written
+ * @param[in] i_accessType DeviceFW::AccessType enum (usrif.H)
+ * @param[in] i_args This is an argument list for DD framework.
+ * In this function, there's only one argument,
+ * containing the PNOR address and chip select
+ * @return errlHndl_t
+ */
+errlHndl_t ddWrite(DeviceFW::OperationType i_opType,
+ TARGETING::Target* i_target,
+ void* io_buffer,
+ size_t& io_buflen,
+ int64_t i_accessType,
+ va_list i_args)
+{
+ errlHndl_t l_err = NULL;
+ uint64_t l_addr = va_arg(i_args,uint64_t);
+
+ do{
+ l_err = Singleton<PnorDD>::instance().write(io_buffer,
+ io_buflen,
+ l_addr);
+ if(l_err)
+ {
+ break;
+ }
+
+ }while(0);
+
+ return l_err;
+}
+
+// Register PNORDD access functions to DD framework
+DEVICE_REGISTER_ROUTE(DeviceFW::READ,
+ DeviceFW::PNOR,
+ TARGETING::TYPE_PROC,
+ ddRead);
+
+DEVICE_REGISTER_ROUTE(DeviceFW::WRITE,
+ DeviceFW::PNOR,
+ TARGETING::TYPE_PROC,
+ ddWrite);
+
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+errlHndl_t setLSCAccessMode(lscMode i_mode)
+{
+ errlHndl_t l_err = NULL;
+
+ do{
+ l_err = Singleton<PnorDD>::instance().setAccessMode(i_mode);
+ if(l_err)
+ {
+ break;
+ }
+
+ }while(0);
+
+ return l_err;
+}
+
+
+/**
+ * @brief Read PNOR
+ */
+errlHndl_t PnorDD::read(void* o_buffer,
+ size_t& io_buflen,
+ uint64_t i_address)
+{
+ TRACDCOMP(g_trac_pnor, "PnorDD::read(i_address=0x%llx)> ", i_address);
+ errlHndl_t l_err = NULL;
+
+ do{
+ //mask off chip select for now, will probably break up fake PNOR into
+ //multiple fake chips eventually
+ uint64_t l_address = i_address & 0x00000000FFFFFFFF;
+
+ l_err = verifyAddressRange(l_address, io_buflen);
+ if(l_err)
+ {
+ io_buflen = 0;
+ break;
+ }
+
+ //create a pointer to the offset start.
+ char * srcPtr = (char *)(FAKE_PNOR_START+l_address);
+
+ //@TODO: likely need a mutex around HW access
+
+ //copy data from memory into the buffer.
+ memcpy(o_buffer, srcPtr, io_buflen);
+
+
+ }while(0);
+
+ return l_err;
+}
+
+/**
+ * @brief Write PNOR
+ */
+errlHndl_t PnorDD::write(void* i_buffer,
+ size_t& io_buflen,
+ uint64_t i_address)
+{
+ TRACDCOMP(g_trac_pnor, "PnorDD::write(i_address=0x%llx)> ", i_address);
+ errlHndl_t l_err = NULL;
+
+ do{
+ //mask off chip select for now, will probably break up fake PNOR into
+ //multiple fake chips eventually
+ uint64_t l_address = i_address & 0x00000000FFFFFFFF;
+
+
+ l_err = verifyAddressRange(l_address, io_buflen);
+ if(l_err)
+ {
+ io_buflen = 0;
+ break;
+ }
+
+ //create a pointer to the offset start.
+ char * destPtr = (char *)(FAKE_PNOR_START+l_address);
+
+ //@TODO: likely need a mutex around HW access
+
+ //copy data from memory into the buffer.
+ memcpy(destPtr, i_buffer, io_buflen);
+
+
+ }while(0);
+
+ return l_err;
+}
+
+/**
+ * @brief Set PNOR to desired mode
+ */
+errlHndl_t PnorDD::setAccessMode(lscMode i_mode)
+{
+ errlHndl_t l_err = NULL;
+ TRACFCOMP(g_trac_pnor, "PnorDD::setAccessMode(0x%llx)> ", i_mode);
+
+ do{
+ //@TODO: real impelementation needed
+
+ //Once we have a 'real' implementation, it will likely drive the need for mutexes
+ //throughout the PnorDD interfaces, to avoid issues with weak consistency or a
+ //read/write occuring while we're updating the mode, but
+ //skipping that until it's actually needed.
+
+ //Eventually need to actually change HW state here.
+ //For now, just record the new mode.
+ iv_lscMode = i_mode;
+
+
+ }while(0);
+
+ return l_err;
+}
+
+
+/********************
+ Private/Protected Methods
+ ********************/
+
+
+/**
+ * @brief Constructor
+ */
+PnorDD::PnorDD()
+: iv_lscMode(MMRD)
+{
+ TRACFCOMP(g_trac_pnor, "PnorDD::PnorDD()> ");
+
+}
+
+/**
+ * @brief Destructor
+ */
+PnorDD::~PnorDD()
+{
+
+ //Nothing todo for now
+}
+
+errlHndl_t PnorDD::verifyAddressRange(uint64_t i_address,
+ size_t& i_length)
+{
+ errlHndl_t l_err = NULL;
+
+ do{
+
+ if((i_address < FAKE_PNOR_START) ||
+ ((i_address+i_length) > FAKE_PNOR_END))
+ {
+ //@TODO create errorlog
+ break;
+ }
+
+
+
+ }while(0);
+
+ return l_err;
+}
+
+
+
+}; //end PNOR namespace
diff --git a/src/usr/pnor/pnordd.H b/src/usr/pnor/pnordd.H
new file mode 100644
index 000000000..df953e203
--- /dev/null
+++ b/src/usr/pnor/pnordd.H
@@ -0,0 +1,98 @@
+#ifndef __PNOR_PNORDD_H
+#define __PNOR_PNORDD_H
+
+/** @file pnordd.H
+ * @brief Provides the interfaces to the PNOR Device Driver
+ */
+
+namespace PNOR
+{
+
+//Not sure if this is the right place for these enums, open to suggestions.
+/**
+ * PNOR Modes
+ */
+enum lscMode
+{
+ MMRD = 0, /**< Indicates PNOR is in MMRD Mode */
+ PMWR, /**< Indicates PNOR is in PMWR Mode */
+
+ LAST_MODE = PMWR,
+};
+
+
+/**
+ * @brief Type definition for PNOR address
+ */
+typedef uint64_t PNORAddress_t;
+
+
+//@TODO: comment args
+/**
+ * @brief External interface for setting LSC mode
+ */
+errlHndl_t setLSCAccessMode(lscMode i_mode);
+
+
+
+class PnorDD
+{
+
+ public:
+ //@TODO: comment args
+ /**
+ * @brief Performs an PNOR Read Operation
+ */
+ errlHndl_t read(void* o_buffer,
+ size_t& io_buflen,
+ uint64_t i_address);
+
+ //@TODO: comment args
+ /**
+ * @brief Performs an PNOR Write Operation
+ */
+ errlHndl_t write(void* i_buffer,
+ size_t& io_buflen,
+ uint64_t i_address);
+
+ //@TODO: comment args
+ /**
+ * @brief Set LSC to desired access mode
+ */
+ errlHndl_t setAccessMode(lscMode i_mode);
+
+
+
+ protected:
+ /**
+ * @brief Constructor
+ */
+ PnorDD();
+
+
+ /**
+ * @brief Destructor
+ */
+ ~PnorDD();
+
+ //@TODO: comment args
+ /**
+ * Verify Request is in appropriate address range
+ *
+ */
+ errlHndl_t verifyAddressRange(uint64_t i_address,
+ size_t& i_length);
+
+
+ private:
+
+ /**
+ * PNOR Mode Flag
+ */
+ lscMode iv_lscMode;
+
+};
+
+}; //end PNOR namespace
+
+#endif
diff --git a/src/usr/pnor/test/makefile b/src/usr/pnor/test/makefile
index a499d93c4..9e8a10c59 100644
--- a/src/usr/pnor/test/makefile
+++ b/src/usr/pnor/test/makefile
@@ -1,6 +1,6 @@
ROOTPATH = ../../../..
-MODULE = pnorrptest
+MODULE = testpnor
TESTS = *.H
include ${ROOTPATH}/config.mk
diff --git a/src/usr/pnor/test/pnorddtest.H b/src/usr/pnor/test/pnorddtest.H
new file mode 100644
index 000000000..a60d53efe
--- /dev/null
+++ b/src/usr/pnor/test/pnorddtest.H
@@ -0,0 +1,130 @@
+#ifndef __PNORDDTEST_H
+#define __PNORDDTEST_H
+
+/**
+ * @file pnorddtest.H
+ *
+ * @brief Test case for PNOR Resource Provider
+*/
+
+#include <cxxtest/TestSuite.H>
+#include <errl/errlmanager.H>
+#include <errl/errlentry.H>
+#include <errl/errltypes.H>
+#include <pnor/pnorif.H>
+#include <devicefw/userif.H>
+//#include "../pnordd.H"
+
+extern trace_desc_t* g_trac_pnor;
+using namespace TARGETING;
+
+
+class PnorDdTest : public CxxTest::TestSuite
+{
+ public:
+
+ /**
+ * @brief PNOR DD test #1
+ * Write some data to PNOR and read it back again
+ */
+ void testPnorDD1(void)
+ {
+ //@TODO: make this table driven so it can test more values
+ //@TODO: compare results with expected data.
+ //@TODO: Add some more interesting tests
+
+ TARGETING::Target* l_testTarget = MASTER_PROCESSOR_CHIP_TARGET_SENTINEL;
+ size_t l_size = sizeof(uint64_t);
+ errlHndl_t l_err = NULL;
+
+ do{
+ TS_TRACE("testPnorDD1: starting");
+
+ // Perform PnorDD Write 1
+ uint64_t l_address = 0x100;
+ uint64_t l_writeData = 0x12345678FEEDB0B0;
+ l_err = deviceWrite(l_testTarget,
+ &l_writeData,
+ l_size,
+ DEVICE_PNOR_ADDRESS(0, l_address));
+ if (l_err)
+ {
+ TS_FAIL("testPnorDD1: PNORDD write 1: deviceWrite() failed! Error committed.");
+ break;
+ }
+ else
+ {
+ TS_TRACE("testPnorDD1: PNORDD write 1, Address 0x%llx, Data %llx",
+ l_address,
+ (long long unsigned)l_writeData);
+ }
+
+
+ // Perform PnorDD Write 2
+ l_address = 0x108;
+ l_writeData = 0xFEEDBEEF000ABCDE;
+ l_err = deviceWrite(l_testTarget,
+ &l_writeData,
+ l_size,
+ DEVICE_PNOR_ADDRESS(0, l_address));
+ if (l_err)
+ {
+ TS_FAIL("testPnorDD1: PNORDD write 2: deviceWrite() failed! Error committed.");
+ break;
+ }
+ else
+ {
+ TS_TRACE("testPnorDD1: PNORDD write 2, Address 0x%llx, Data %llx",
+ l_address,
+ (long long unsigned)l_writeData);
+ }
+
+ // Perform PnorDD read 1
+ l_address = 0x100;
+ uint64_t l_readData = 0;
+ l_err = deviceRead(l_testTarget,
+ &l_readData,
+ l_size,
+ DEVICE_PNOR_ADDRESS(0, l_address));
+ if (l_err)
+ {
+ TS_FAIL("testPnorDD1: PNORDD read 1: deviceRead() failed! Error committed.");
+ break;
+ }
+ else
+ {
+ TS_TRACE("testPnorDD1: PNORDD read 1, Address 0x%llx, Data %llx",
+ l_address,
+ (long long unsigned)l_readData);
+ }
+
+ // Perform PnorDD read 2
+ l_address = 0x108;
+ l_err = deviceRead(l_testTarget,
+ &l_readData,
+ l_size,
+ DEVICE_PNOR_ADDRESS(0, l_address));
+ if (l_err)
+ {
+ TS_FAIL("testPnorDD1: PNORDD read 2: deviceRead() failed! Error committed.");
+ break;
+ }
+ else
+ {
+ TS_TRACE("testPnorDD1: PNORDD read 2, Address 0x%llx, Data %llx",
+ l_address,
+ (long long unsigned)l_readData);
+ }
+
+ }while(0);
+
+
+ //@TODO: Add total fail/pass count trace to know how many passed.
+
+ };
+
+
+};
+
+
+#endif
OpenPOWER on IntegriCloud