diff options
Diffstat (limited to 'src/lib/gpe_scom.h')
-rw-r--r-- | src/lib/gpe_scom.h | 471 |
1 files changed, 471 insertions, 0 deletions
diff --git a/src/lib/gpe_scom.h b/src/lib/gpe_scom.h new file mode 100644 index 0000000..3f8f26e --- /dev/null +++ b/src/lib/gpe_scom.h @@ -0,0 +1,471 @@ +#ifndef __GPE_SCOM_H__ +#define __GPE_SCOM_H__ + +// $Id: gpe_scom.h,v 1.1.1.1 2013/12/11 20:49:20 bcbrock Exp $ +// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/gpe_scom.h,v $ +//----------------------------------------------------------------------------- +// *! (C) Copyright International Business Machines Corp. 2013 +// *! All Rights Reserved -- Property of IBM +// *! *** IBM Confidential *** +//----------------------------------------------------------------------------- + +/// \file gpe_scom.h +/// \brief Generic SCOM procedures for PORE-GPE +/// +/// We provide 2 generic SCOM procedures for PORE-GPE, one for P8 SCOMs and +/// another for Centaur SCOMS. The setup and control of the procedures is +/// roughly modeled after the way the simple SCOM-ing programs were described +/// and implemented by the P7 OCA unit. This facility was written primarily to +/// support SCOM-ing Centaur from OCC (which requires a complex setup), +/// however for some core applications it may also be simpler to use a generic +/// procedure rather than creating a custom GPE program to read/write P8 SCOM +/// registers. +/// +/// SCOM programs are set up and controlled through a GpeScomParms +/// structure. This structure contains overall control and status information, +/// as well as a pointer to an array of scomList_t structures which decribes +/// the program. Each entry of the scomList_t describes one of several +/// operations that can be performed on a SCOM address including read, write, +/// and read-modify-write. Special control-only entries are also supported +/// including a NOP, a programmable wait delay, timestamping with the TOD and +/// special "SYNC" commands for Centaur. For more on the commands and their +/// actions please see \ref gpe_scom_commands. +/// +/// Each scomList_t entry also includes a data field and a mask field. The +/// data field contains the data to write for SCOM writes and +/// read-modify-writes, holds the data returned for SCOM reads, or contains a +/// pointer to a data vector for vector commands. The mask is used in the case +/// of read-modify-write to indicate which bits of the SCOM to modify. Control +/// commands may also interpret these fields in different ways. + + +#ifndef __ASSEMBLER__ + +/// A SCOM command descriptor for gpe_scom_centaur amd gpe_scom_p8. +/// +/// For an introduction to the use of this structure and the procedures that +/// use please see the commants for the file gpe_scom.h +/// +/// The \a scom field is the full 32-bit SCOM address of the targeted SCOM, +/// initialized by the caller. SCOM addresses for P8 core SCOMs can be +/// created from the chiplet-0 address using the macro +/// CORE_CHIPLET_ADDRESS(). Multicast addresses for P8 can be generated using +/// the macro MC_ADDRESS(). The notions of internal "chiplets" and "multicast" +/// are not supported for Centaur SCOM addreses, so for Centaur this is always +/// a simple SCOM address. The procedure gpe_scom_centaur() does support an +/// iterative notion of multicast however. Some special control commands do +/// not use this field at all; see \ref gpe_scom_commands. +/// +/// The \a errorFlags field contains error status associated with the +/// (attempted) SCOM access. This field is set by the procedure. For futher +/// informaton on error handling please see each individual procedure. +/// +/// The \a instanceNumber field is currently only used by +/// gpe_scom_centaur(). For further details please see the documentation for +/// gpe_scom_centaur(). +/// +/// The \a commandType field is initialized by the caller. For command +/// documentation see \ref gpe_scom_commands and the individual procedures. +/// +/// The \a data field is used to hold write data for SCOM write and +/// read-modify-write commands (including the "all" forms), contains the +/// returned read data for scalar SCOM read commands, and contains a pointer +/// to a data vector for vector commands. Other commands may also use the \a +/// data field for other purposes as documented with each command. +/// +/// The \a mask field contains a positive bit mask used to identify the fields +/// to update for SCOM read-modify-write. Other commands may also use the \a +/// mask field for other purposes as documented with each command. +/// +/// \note Because this structure is read and written by the GPE engine it is +/// strongly recommended to allocate instances of this structure in +/// non-cacheable data sections, with the caveat that data structures assigned +/// to non-default data sections must always be initialized. For example: +/// +/// \code +/// +/// static scomList_t S_scomList[10] +/// SECTION_ATTRIBUTE(".noncacheable") = {0}; +/// +/// \endcode + +typedef struct { + union + { + struct { + uint32_t scom; + uint8_t reserved; + uint8_t errorFlags; + uint8_t instanceNumber; + uint8_t commandType; + }; + uint64_t command; + }; + uint64_t mask; + union + { + uint64_t data; + struct { + uint32_t unused; + uint64_t* pData; + }; + }; +} scomList_t; + +#else // __ASSEMBLER__ + + // scomList_t structure offsets + + .set SCOM_LIST_COMMAND, 0x0 + .set SCOM_LIST_MASK, 0x8 + .set SCOM_LIST_DATA, 0x10 + .set SIZEOF_SCOM_LIST_T, 0x18 + + // PGAS macros to extract fields of the scomList_t command. The source + // and target must be data registers, and they can be the same data + // register. + + .macro scom_list_get_scom, target:req, source:req + extrdi \target, \source, 32, 0 + .endm + + .macro scom_list_get_instance_number, target:req, source:req + extrdi \target, \source, 8, 48 + .endm + + .macro scom_list_get_command_type, target:req, source:req + extrdi \target, \source, 8, 56 + .endm + + // PGAS macros to update fields of the scomList_t command. The source + // and target must be different data registers. The target is the + // current value and is updated with the new field held + // right-justified in the source. The source register is effectively + // destroyed by these operations. + + .macro scom_list_set_error_flags, target:req, source:req + insrdi \target, \source, 8, 40 + .endm + + .macro scom_list_set_instance_number, target:req, source:req + insrdi \target, \source, 8, 48 + .endm + +#endif // __ASSEMBLER__ + +/// \defgroup gpe_scom_commands GPE SCOM Procedure Commands +/// +/// \note Command 0 is not defined on purpose to trap errors. +/// @{ + +/// No operation +#define GPE_SCOM_NOP 1 + +/// Read from SCOM, depositing read data into the \a data field of the +/// scomList_t. +#define GPE_SCOM_READ 2 + +/// Write to SCOM, taking write data from the \a data field of the scomList_t. +#define GPE_SCOM_WRITE 3 + +/// Read-Modify-Write. +/// +/// This operation first reads the SCOM. Bits under the \a mask field of the +/// scomList_t are then cleared in the read data. The masked read data is then +/// ORed with the contents of the \a data field of the scomList_t and the +/// result is written back to the SCOM address. +/// +/// \note This command \e does \e not apply the mask to the data from the \a +/// data field of the scomList_t. The caller should do this (if necessary) +/// when setting up the scomList_t. +/// +/// \note The procedures do not provide a way to distinguish errors that may +/// have occurred on the initial read vs. those that may have occurred on the +/// subsequenct write. +#define GPE_SCOM_RMW 4 + +/// For gpe_scom_centaur(), the \a data field of the scomList_t contains a +/// 32-bit pointer (cast to a uint64_t) to an array of PGP_NCENTAUR uint64_t +/// values. SCOM read data for each configured Centaur (MCS) is deposited in +/// this array. Array entries for unconfigured Centaur are zeroed. +#define GPE_SCOM_READ_VECTOR 5 + +/// For gpe_scom_centaur(), write the \a data field of the scomList_t to +/// all configured Centaur. Currently unsupported for gpe_scom_p8(). +#define GPE_SCOM_WRITE_ALL 6 + +/// For gpe_scom_centaur(), perform read-modify write for all configured +/// Centaur. Currently unsupported for gpe_scom_p8(). +#define GPE_SCOM_RMW_ALL 7 + +/// Programmable wait delay +/// +/// This command simply waits for an interval of time specified by the \a data +/// field of the scomList_t. Use the macro GPE_SCOM_WAIT_DELAY() to convert +/// SSX (OCC timebase) ticks into the correct units for this command. For +/// example use GPE_SCOM_WAIT_DELAY(SSX_MILLISECONDS(10)) to wait 10 ms. +/// +/// \note This operation blocks the GPE from completing any other work until +/// the delay is finished. +/// +/// \note This time delay can not be implemented with extreme precision due to +/// the lack of a programmable wait delay in the PORE architecture, plus +/// procedure overhead, bus and bus interface contention, etc. For +/// applications requiring extremely precise timing it will be best to code +/// those by hand in PORE assembler and run them in a dedicated lab-only +/// setting. +#define GPE_SCOM_WAIT 8 + +/// Issue a generic Centaur SYNC +/// +/// This command is only valid for gpe_scom_centaur(). This command creates +/// and issues a generic SYNC command to Centaur. The caller is completely +/// responsible for creating the contents of the data packet sent as part of +/// the Centaur SYNC. The data packet is taken verbatim from the \a data field +/// of the scomList_t, and sent to the MCS designated as the SYNC MCS in the +/// global G_centaurConfiguration. For further details see the comments with +/// the procedure gpe_scom_centaur() and the CentaurConfiguration structure. +#define GPE_SCOM_CENTAUR_SYNC 9 + +/// Issue a Centaur SYNC to all configured Centaur +/// +/// This command is only valid for gpe_scom_centaur(). This command creates +/// and issues a SYNC command to all configured Centaur. The data packet is +/// taken from the \a data field of the scomList_t, and sent to the MCS +/// designated as the SYNC MCS in the global G_centaurConfiguration. The +/// caller is responsible for setting the SYNC command bits (bits 8:N); The +/// procedure will fill bits 0:7 with a mask of all configured Centaur. For +/// further details see the comments with the procedure gpe_scom_centaur() and +/// the CentaurConfiguration structure. +#define GPE_SCOM_CENTAUR_SYNC_ALL 10 + +/// Read the TOD clock +/// +/// This command reads the TOD clock and deposits the value into the \a data +/// field of the scomList_t. +#define GPE_SCOM_TOD 11 + +/// @} + + +#ifndef __ASSEMBLER__ + +/// \defgroup centaur_sync_commands Centaur SYNC Command Bits +/// +/// The Centaur SYNC command is an 8-byte word written to a specific in-band +/// address. SYNC commands are generated by the gpe_scom_centaur() procedure +/// in response to the GPE_SCOM_CENTAUR_SYNC and GPE_SCOM_CENTAUR_SYNC_ALL +/// commands (which see). +/// +/// \note From the MCS Unit Workbook: Note that only the N/M Throttle sync +/// command will be used operationally in P-series, although if will be +/// possible to test all the sync commands in P-series lab testing. Z-series +/// will use all specified sync command types. ... Valid combinations of bits +/// (8:15) are: b00000000, bVVVVVV0V, and b00000010, where V = 0 or 1. +/// +/// @{ + +#define CENTAUR_GENERATE_REFRESH_COUNTER_SYNC 0x0080000000000000ull +#define CENTAUR_RESET_CALIBRATION_COUNTER_1_SYNC 0x0040000000000000ull +#define CENTAUR_RESET_CALIBRATION_COUNTER_2_SYNC 0x0020000000000000ull +#define CENTAUR_RESET_CALIBRATION_COUNTER_3_SYNC 0x0010000000000000ull +#define CENTAUR_RESET_N_M_THROTTLE_COUNTER_SYNC 0x0008000000000000ull +#define CENTAUR_RESET_MB_TIMEBASE_SYNC 0x0004000000000000ull +#define CENTAUR_SUPER_SYNC 0x0002000000000000ull +#define CENTAUR_MYSTERY_SYNC 0x0001000000000000ull + +/// \todo Figure out what is the "mystery sync" + +/// @} + + +/// Convert an SsxInterval to a delay specification for gpe_scom_*() + +// Yes, Virginia, the PORE engine takes 20 cycles to decrement and branch :( +#define GPE_SCOM_WAIT_DELAY(x) ((x) / 20) + + +/// Parameters for gpe_scom_centaur() and gpe_scom_p8(). +/// +/// A pointer to an initialized GpeScomParms structure is passed as the +/// parameter to the GPE procedures gpe_scom_centaur() and gpe_scom_p8. +/// +/// \note Because this structure is read and written by the GPE engine it is +/// strongly recommended to allocate instances of this structure in +/// non-cacheable data sections, with the caveat that data structures assigned +/// to non-default data sections must always be initialized. For example: +/// +/// \code +/// +/// static GpeScomParms S_scomParms +/// SECTION_ATTRIBUTE(".noncacheable") = {0}; +/// +/// \endcode + +typedef struct { + + /// Input: The SCOM list + /// + /// This is a right-justfied pointer to an array of scomList_t structures + /// describing the sequence of commands to execute. + uint64_t scomList; + + /// Input: The number of entries in the scomList. + /// + /// \note It is considered an error if \a entries is 0, under the + /// assumption that the caller must have neglected to initialize the + /// structure. + uint32_t entries; + + /// Input: Procedure options + /// + /// An OR-mask of option flags; See \ref gpe_scom_options; + uint32_t options; + + /// Output: The procedure return code + /// + /// This field will contain 0 in the event of a successful return, and a + /// non-zero value in the event of an error. See \ref gpe_scom_rc for + /// documentation of the possible return codes. + uint32_t rc; + + /// Output: The index of the entry that failed + /// + /// In the event that \a rc != 0, this field will contain the 0-based + /// index of the \a scomList entry that was being processed at the time of + /// the failure, or -1 for failures associated with the parameters or + /// setup of the procedure. + int32_t errorIndex; + +} GpeScomParms; + +#else // __ASSEMBLER__ + + // Offsets into the GpeScomParms structure + + .set GPE_SCOM_PARMS_SCOM_LIST, 0x00 + .set GPE_SCOM_PARMS_ENTRIES_OPTIONS, 0x08 + .set GPE_SCOM_PARMS_RC_ERROR_INDEX, 0x10 + + // PGAS macros to extract fields of the GpeScomParms. The source + // and target must be data registers, and they can be the same data + // register. + + .macro gpe_scom_parms_get_entries, target:req, source:req + extrdi \target, \source, 32, 0 + .endm + + .macro gpe_scom_parms_get_options, target:req, source:req + extrdi \target, \source, 32, 32 + .endm + + .macro gpe_scom_parms_get_rc, target:req, source:req + extrdi \target, \source, 32, 0 + .endm + + // PGAS macros to update fields of the GpeScomParms. The source + // and target must be different data registers. The target is the + // current value and is updated with the new field held + // right-justified in the source. The source register is effectively + // destroyed by these operations. + + .macro gpe_scom_parms_set_rc, target:req, source:req + insrdi \target, \source, 32, 0 + .endm + + .macro gpe_scom_parms_set_error_index, target:req, source:req + insrdi \target, \source, 32, 32 + .endm + +#endif // __ASSEMBLER__ + + +/// \defgroup gpe_scom_rc Return Codes From GPE SCOM Procedures +/// +/// @{ + +/// Successful completion of a GPE SCOM program +#define GPE_SCOM_SUCCESS 0 + +/// An error occurred during setup of the PBA for Centaur access. If this +/// error code is returned then the \a errorIndex field of the GpeScomParms +/// structure will be set to -1. +#define GPE_SCOM_SETUP_ERROR 1 + +/// One of the fields of the GpeScomParms structure is invalid. In the case of +/// gpe_scom_centaur(), this code may also be returned if there is a problem +/// with the global structure G_centaurConfiguration. If this error code is +/// returned then the \a errorIndex field of the GpeScomParms structure will +/// be set to -1 if the error occurred before command processing begins. +#define GPE_SCOM_INVALID_ARGUMENT 2 + +/// The procedure died. Since GPE procedures do not trap errors by default +/// they will typically die on the first hardware-detected error, and GPE +/// error recovery procedures will clean up the failed job. If this error code +/// is returned then the \a errorIndex field of the GpeScomParms structure +/// will indicate the \a scomList entry being processed at the time of the +/// failure. +#define GPE_SCOM_DIED 3 + +/// The \a commandType field of the scomList_t was not valid for the procedure. +/// When this error is signalled then the \a errorIndex field of the +/// GpeScomParms structure contains the index of the failing entry. +#define GPE_SCOM_INVALID_COMMAND 4 + +/// Signalled only by gpe_scom_centaur(), the \a instanceNumber field of the +/// scomList_t did not index a valid (configured) Centaur. This error is only +/// signalled by the GPE_SCOM_READ, GPE_SCOM_WRITE and GPE_SCOM_RMW commands +/// that require a valid Centaur to be specified. When this error is signalled +/// then the \a errorIndex field of the GpeScomParms structure contains the +/// index of the failing entry. +#define GPE_SCOM_INVALID_CENTAUR 5 + +/// @} + + +/// Execute a SCOM program for Centaur SCOMs +/// +/// \param[in,out] io_parms A pointer to an initialized GpeScomParms +/// structure. Since this structure is used both for input of parameterization +/// and output of return codes it is imperitive that this structure is +/// allocated in non-cacheable memory to avoid cache-related bugs. See the +/// documentation for the fields of GpeScomParms for more information. +/// +/// gpe_scom_centaur() is a GPE program that takes a pointer to an initialized +/// GpeScomParms structure as input and executes the list of SCOMs and other +/// commands. Return codes are returned in the GpeScomParms. +/// +/// The following notes relate to the fields of the scomList_t structure when +/// used by gpe_scom_centaur(). +/// +/// - \a instanceNumber : This field must be set to the index (0 - 7) of the +/// Centaur (MCS) to access for the commands GPE_SCOM_READ, GPE_SCOM_WRITE and +/// GPE_SCOM_RMW. This field is ignored by other commands. +/// +/// - \a commandType : gpe_scom_centaur() supports the special command types +/// GPE_SCOM_CENTAUR_SYNC and GPE_CENTAUR_SYNC_ALL as documented in \ref +/// gpe_scom_commands. +/// +/// - \a data : The commands GPE_SCOM_CENTAUR_SYNC and +/// GPE_SCOM_CENTAUR_SYNC_ALL require a unique format for the \a data field as +/// documented with the command. +#ifdef DOXYGEN_ONLY +void gpe_scom_centaur(GpeScomParms *io_parms); +#endif + +#ifndef __ASSEMBLER__ + +// Procedure entry points + +PoreEntryPoint gpe_scom_centaur; +PoreEntryPoint gpe_scom_p8; + +// Debugging symbols + +extern uint64_t G_gsc_lastSlaveControl SECTION_ATTRIBUTE(".data.pore"); +extern uint64_t G_gsc_lastScomAddress SECTION_ATTRIBUTE(".data.pore"); +extern uint64_t G_gsc_lastOciAddress SECTION_ATTRIBUTE(".data.pore"); + +#endif // __ASSEMBLER__ + +#endif // __GPE_SCOM_H__ |