diff options
Diffstat (limited to 'src/lib/gpe_pba.c')
-rwxr-xr-x | src/lib/gpe_pba.c | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/src/lib/gpe_pba.c b/src/lib/gpe_pba.c new file mode 100755 index 0000000..c3b0a00 --- /dev/null +++ b/src/lib/gpe_pba.c @@ -0,0 +1,148 @@ +// $Id: gpe_pba.c,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_pba.c,v $ +//----------------------------------------------------------------------------- +// *! (C) Copyright International Business Machines Corp. 2013 +// *! All Rights Reserved -- Property of IBM +// *! *** IBM Confidential *** +//----------------------------------------------------------------------------- + +/// \file gpe.c +/// \brief Generic PORE-GPE support procesures (outside of the kernel +/// drivers). + +#include "ssx.h" +#include "gpe.h" +#include "gpe_pba.h" + +/// Create/initialize a GpePbaParms structure +/// +/// \param parms A unused or uninitialized GpePbaParms structure +/// +/// \param slave The PBA slave port to program. For production code this will +/// normally be PBA_SLAVE_PORE_GPE, however for test/verification code it +/// could be any PBA slave. +/// +/// \param write_ttype One of PBA_WRITE_TTYPE_* (see pgp_pba.h). Use +/// PBA_WRITE_TTYPE_DC (don't care) if the GPE application does not do writes. +/// +/// \param write_tsize One of PBA_WRITE_TSIZE_* (see pgp_pba.h). The \a +/// write_tsize is only relevant for \a write_ttype == PBA_WRITE_TTYPE_LCO_M, +/// where the macro PBA_WRITE_TSIZE_CHIPLET() is used to specify the target +/// chiplet, and \a write_ttype == PBA_WRITE_TTYPE_ATOMIC_RMW, where the \a +/// write_tsize specifies the atomic operation. Otherwise use +/// PBA_WRITE_TTYPE_DC (don't care). +/// +/// \param read_ttype One of PBA_READ_TTYPE_* (see pgp_pba.h). Normally this +/// will be PBA_READ_TTYPE_CL_READ_NC (or PBA_READ_TTYPE_DC if you don't +/// care.) +/// +/// \param flags Two flags are provided that override default +/// behavior. GPE_PBA_PARMS_READ_INVALIDATE specifies read buffer invalidation +/// after every read. This is always selected when the read Ttype is a +/// cache-inhibited partial read, but may be optionally specified for test +/// purposes. +/// +/// Similarly, GPE_PBA_PARMS_DISABLE_WRITE_GATHER specifies that write +/// gathering for write Ttype DMA partial write is disabled. Note that +/// GPE_PBA_PARMS_DISABLE_WRITE_GATHER disables write gathering in the sense +/// that writes pass through the PBA immediately without being buffered. This +/// is different from using the PBA_WRITE_GATHER_TIMEOUT_DISABLE option to \a +/// write_gather_timeout, which specifies that writes are gathered until an +/// entire line is filled. +/// +/// This API initializes the GpePbaParms structure used by every GPE program +/// that accesses mainstore via PBA. It creates an image of a PBA_SLVCTL +/// register to be applied under a mask. +/// +/// \note Read buffer invalidation is always enforced for cache-inhibited +/// partial reads. This also forces prefetching to be disabled for the +/// slave. Our procedures currently do not support save/restore of prefetch +/// controls as different tasks reprogram the PBA Slave. Thus any access of a +/// shared slave that is also used to do CI_PR_RD will have prefetching +/// disabled. +/// +/// \retval 0 Success +/// +/// \retval -GPE_INVALID_OBJECT The \a parms pointer is NULL (0) or othewise +/// invalid. +/// +/// \retval -GPE_INVALID_ARGUMENT One of the arguments is invalid in some way. + +int +gpe_pba_parms_create(GpePbaParms *parms, + int slave, + int write_ttype, + int write_tsize, + int read_ttype) +{ + pba_slvctln_t *slvctl, *mask; + pba_slvrst_t* slvrst; + pba_slvrst_t* slvrst_in_progress; + uint64_t all1 = 0xffffffffffffffffull; + + + if (SSX_ERROR_CHECK_API) { + SSX_ERROR_IF((parms == 0), GPE_INVALID_OBJECT); + SSX_ERROR_IF((slave < 0) || + (slave >= PBA_SLAVES), + GPE_INVALID_ARGUMENT); + } + + parms->slave_id = slave; + + slvctl = &(parms->slvctl); + mask = &(parms->mask); + slvrst = &(parms->slvrst); + slvrst_in_progress = &(parms->slvrst_in_progress); + + parms->slvctl_address = PBA_SLVCTLN(slave); + + slvrst->value = 0; + slvrst->fields.set = PBA_SLVRST_SET(slave); + + slvrst_in_progress->value = 0; + slvrst_in_progress->fields.in_prog = PBA_SLVRST_IN_PROG(slave); + + slvctl->value = 0; + mask->value = 0; + + slvctl->fields.enable = 1; + mask->fields.enable = all1; + + slvctl->fields.write_ttype = write_ttype; + mask->fields.write_ttype = all1; + + slvctl->fields.write_tsize = write_tsize; + mask->fields.write_tsize = all1; + + slvctl->fields.read_ttype = read_ttype; + mask->fields.read_ttype = all1; + + if (read_ttype == PBA_READ_TTYPE_CI_PR_RD) { + + slvctl->fields.buf_invalidate_ctl = 1; + mask->fields.buf_invalidate_ctl = all1; + + slvctl->fields.read_prefetch_ctl = PBA_READ_PREFETCH_NONE; + mask->fields.read_prefetch_ctl = all1; + + } else { + + slvctl->fields.buf_invalidate_ctl = 0; + mask->fields.buf_invalidate_ctl = all1; + } + + mask->value = ~(mask->value); + + return 0; +} + + + + + + + + + + |