From 5867b512c1592fce1a5bab56e4320efd6598645f Mon Sep 17 00:00:00 2001 From: Adam Muhle Date: Tue, 26 Jul 2011 09:57:45 -0500 Subject: 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 --- src/usr/pnor/pnordd.C | 301 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 301 insertions(+) create mode 100644 src/usr/pnor/pnordd.C (limited to 'src/usr/pnor/pnordd.C') 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include "pnordd.H" +#include + +#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::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::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::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 -- cgit v1.2.1