From 26a86256282eb6ff0e5816207785e4382c258980 Mon Sep 17 00:00:00 2001 From: Dan Crowell Date: Mon, 3 Dec 2012 22:12:51 -0600 Subject: VPD Write Enable SPD writes and send a message to the FSP to update the real VPD. Change-Id: Ia398a49b4b5e2505c3ac25176cf37a5a0fc28111 RTC: 41365 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/2549 Reviewed-by: A. Patrick Williams III Tested-by: Jenkins Server --- src/include/usr/mbox/mbox_queues.H | 4 ++- src/include/usr/spd/spdenums.H | 41 ++++++++++++++++++++++ src/include/usr/spd/spdif.H | 34 ++++++++++++++++++ src/usr/spd/dimmPres.C | 50 +++++++++++++------------- src/usr/spd/spd.C | 72 +++++++++++++++++++++++++++++++------- src/usr/spd/spd.H | 14 ++++++-- 6 files changed, 174 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/include/usr/mbox/mbox_queues.H b/src/include/usr/mbox/mbox_queues.H index bb8b9e2b3..1941aec1b 100644 --- a/src/include/usr/mbox/mbox_queues.H +++ b/src/include/usr/mbox/mbox_queues.H @@ -57,8 +57,10 @@ namespace MBOX FSP_ERROR_MSGQ = 0x80000004, IPL_SERVICE_QUEUE = 0x80000008, // Defined by Fsp team FSP_ATTR_SYNC_MSGQ = 0x80000009, - FSP_HWPF_ATTR_MSGQ = 0x8000000b, // HWPF Attribute override/sync + FSP_HWPF_ATTR_MSGQ = 0x8000000B, // HWPF Attribute override/sync + FSP_VPD_MSGQ = 0x8000000C, // Add FSP services here: + FSP_ECHO_MSGQ = 0xFFFFFFFF, // Fake FSP for test }; diff --git a/src/include/usr/spd/spdenums.H b/src/include/usr/spd/spdenums.H index 2c2d6582a..09178c96f 100644 --- a/src/include/usr/spd/spdenums.H +++ b/src/include/usr/spd/spdenums.H @@ -30,6 +30,8 @@ #ifndef __SPDENUMS_H #define __SPDENUMS_H +#include + namespace SPD { @@ -258,6 +260,45 @@ enum INVALID_SPD_KEYWORD = 0xFFFF, }; +/** + * @brief VPD Message Types + */ +enum VPD_MSG_TYPE +{ + VPD_WRITE_DIMM = 0x00C1, //< DIMM SPD + VPD_WRITE_PROC = 0x00C2, //< Processor MVPD + VPD_WRITE_MEMBUF = 0x00C3, //< Centaur FRU VPD +}; + +/** + * @brief Message definition for VPD Write Request + * + * - data0 : + * - [16] VPD Record Number + * - [32] 4-byte ASCII String for record name + * 'XXXX'=Entire VPD section from PNOR + * - [16] 2-byte ASCII String for keyword or offset into SPD + * 'XX'=Entire VPD record + * - data1 : + * - [64] Size of binary data in bytes + * - extra data : Binary VPD Data + */ +union VpdWriteMsg_t +{ + uint64_t data0; + struct + { + uint16_t rec_num; //< VPD_REC_NUM + char record[4]; //< ASCII Record Name + union + { + char keyword[2]; //< ASCII Keyword (for IBM VPD) + uint16_t offset; //< Offset into record in bytes (for DIMM SPD) + }; + } PACKED; +}; + + }; // end SPD #endif diff --git a/src/include/usr/spd/spdif.H b/src/include/usr/spd/spdif.H index c56a8dabf..41bd94ffc 100644 --- a/src/include/usr/spd/spdif.H +++ b/src/include/usr/spd/spdif.H @@ -83,6 +83,40 @@ errlHndl_t readPNOR ( uint64_t i_byteAddr, uint64_t &io_cachedAddr, mutex_t * i_mutex ); +/** + * @brief This function will write the PNOR at the correct offset and number + * of bytes for the keyword requested. + * + * @param[in] i_byteAddr - The offset to access in the PNOR. + * + * @param[in] i_numBytes - The number of bytes to write. + * + * @param[in] i_data - The data buffer of the data to be written. + * + * @param[in] i_target - The chip target to access the data for. + * + * @param[in] i_pnorInfo - Information about the PNOR section and side that we + * need to know to make the request. + * + * @param[in/out] io_cachedAddr - The address offset to the data chunk in + * PNOR. + * + * @param[in] i_mutex - The mutex to lock/unlock while setting io_isAddrCached + * and io_cachedAddr. It is assumed that those parameters are global + * variables in the code where they reside. + * + * @return errlHndl_t - NULL if successful, otherwise a pointer to the error + * log. + */ +errlHndl_t writePNOR ( uint64_t i_byteAddr, + size_t i_numBytes, + void * i_data, + TARGETING::Target * i_target, + pnorInformation & i_pnorInfo, + uint64_t &io_cachedAddr, + mutex_t * i_mutex ); + + }; // end SPD #endif diff --git a/src/usr/spd/dimmPres.C b/src/usr/spd/dimmPres.C index 3cc573414..70d6d36fe 100755 --- a/src/usr/spd/dimmPres.C +++ b/src/usr/spd/dimmPres.C @@ -1,25 +1,25 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/spd/dimmPres.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/spd/dimmPres.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 otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ /** * @file dimmPres.C * @@ -85,7 +85,7 @@ errlHndl_t dimmPresenceDetect( DeviceFW::OperationType i_opType, size_t presentSz = sizeof(present); TRACSSCOMP( g_trac_spd, - ENTER_MRK"spdPresenceDetect()" ); + ENTER_MRK"dimmPresenceDetect()" ); do { @@ -93,7 +93,7 @@ errlHndl_t dimmPresenceDetect( DeviceFW::OperationType i_opType, if( !(io_buflen >= sizeof(bool)) ) { TRACFCOMP( g_trac_spd, - ERR_MRK"spdPresenceDetect() - Invalid Data Length: %d", + ERR_MRK"dimmPresenceDetect() - Invalid Data Length: %d", io_buflen ); /*@ @@ -148,7 +148,7 @@ errlHndl_t dimmPresenceDetect( DeviceFW::OperationType i_opType, } while( 0 ); TRACSSCOMP( g_trac_spd, - EXIT_MRK"spdPresenceDetect()" ); + EXIT_MRK"dimmPresenceDetect()" ); return err; } // end dimmPresenceDetect diff --git a/src/usr/spd/spd.C b/src/usr/spd/spd.C index e6403ef07..ff54fd217 100755 --- a/src/usr/spd/spd.C +++ b/src/usr/spd/spd.C @@ -66,8 +66,8 @@ TRAC_INIT( & g_trac_spd, "SPD", KILOBYTE ); // ------------------------ // Macros for unit testing -//#define TRACUCOMP(args...) TRACFCOMP(args) -#define TRACUCOMP(args...) +#define TRACUCOMP(args...) TRACFCOMP(args) +//#define TRACUCOMP(args...) //#define TRACSSCOMP(args...) TRACFCOMP(args) #define TRACSSCOMP(args...) @@ -616,6 +616,10 @@ errlHndl_t spdWriteValue ( uint64_t i_keyword, break; } + //@todo: RTC:39177 - Need to handle writes that are not on a + // byte boundary by reading the rest of the byte first + assert( (entry->length)%8 == 0 ); + // Write value err = spdWriteData( entry->offset, io_buflen, @@ -628,7 +632,10 @@ errlHndl_t spdWriteValue ( uint64_t i_keyword, } // Send mbox message with new data to Fsp - err = spdSendMboxWriteMsg(); + err = spdSendMboxWriteMsg( entry->offset, + io_buflen, + io_buffer, + i_target ); if( err ) { @@ -1018,27 +1025,68 @@ errlHndl_t spdReadBinaryFile ( uint64_t i_byteAddr, // ------------------------------------------------------------------ // spdSendMboxWriteMsg // ------------------------------------------------------------------ -errlHndl_t spdSendMboxWriteMsg ( void ) +errlHndl_t spdSendMboxWriteMsg ( uint64_t i_offset, + size_t i_numBytes, + void * i_data, + TARGETING::Target * i_target ) { - errlHndl_t err = NULL; + errlHndl_t l_err = NULL; + msg_t* msg = NULL; TRACSSCOMP( g_trac_spd, ENTER_MRK"spdSendMboxWriteMsg()" ); do { - // TODO - Since all writes to SPD will be greather than 16 bytes, - // there is a need for the "extra_data" option from mbox. This is not - // available as of yet. - // - // This will be implemented with Story 41365, which cannot be done - // until story 34032 has been completed. + //Create a mailbox message to send to FSP + msg = msg_allocate(); + msg->type = VPD_WRITE_DIMM; + + VpdWriteMsg_t msgdata; + msgdata.rec_num = i_target->getAttr(); + memcpy( msgdata.record, "XXXX", 4 ); //offset relative to whole section + msgdata.offset = i_offset; + msg->data[0] = msgdata.data0; + msg->data[1] = i_numBytes; + + //should never need more than 4KB + assert( i_numBytes < PAGESIZE); + + msg->extra_data = malloc( i_numBytes ); + memcpy( msg->extra_data, i_data, i_numBytes ); + TRACFCOMP( g_trac_spd, "extra_data=%p", msg->extra_data ); + + TRACFCOMP( g_trac_spd, + INFO_MRK"Send msg to FSP to write record %d, offset 0x%X", + msgdata.rec_num, + msgdata.offset ); + + //Create a mbox message with the error log and send it to FSP + //We only send error log to FSP when mailbox is enabled + if( !MBOX::mailbox_enabled() ) + { + TRACFCOMP(g_trac_spd, INFO_MRK "Mailbox is disabled, skipping SPD write"); + TRACFBIN( g_trac_spd, "msg=", msg, sizeof(msg_t) ); + TRACFBIN( g_trac_spd, "extra=", msg->extra_data, i_numBytes ); + } + + l_err = MBOX::send( MBOX::FSP_VPD_MSGQ, msg ); + if( l_err ) + { + TRACFCOMP(g_trac_spd, ERR_MRK "Failed sending SPD to FSP"); + // just commit the log and move on, nothing else to do + l_err->collectTrace("SPD",1024); + errlCommit( l_err, SPD_COMP_ID ); + l_err = NULL; + + msg_free( msg ); + } } while( 0 ); TRACSSCOMP( g_trac_spd, EXIT_MRK"spdSendMboxWriteMsg()" ); - return err; + return l_err; } diff --git a/src/usr/spd/spd.H b/src/usr/spd/spd.H index a5bf27c5c..83595d5b6 100755 --- a/src/usr/spd/spd.H +++ b/src/usr/spd/spd.H @@ -464,13 +464,21 @@ errlHndl_t writePNOR ( uint64_t i_byteAddr, * @brief This function handles sending the mailbox message to the Fsp to * notify of updates to the data. * - * TODO with Story 41365 - * @param NONE, yet. + * @param[in] i_offset - The offset into the JEDEC SPD layout. + * + * @param[in] i_numbytes - Number of bytes to read. + * + * @param[in] i_data - The data buffer that will return the data read. + * + * @param[in] i_target - The target DIMM to access. * * @return errlHndl_t - NULL if successful, otherwise a pointer to the error * log. */ -errlHndl_t spdSendMboxWriteMsg ( void ); +errlHndl_t spdSendMboxWriteMsg ( uint64_t i_offset, + size_t i_numBytes, + void * i_data, + TARGETING::Target * i_target ); }; // end SPD namespace -- cgit v1.2.1