summaryrefslogtreecommitdiffstats
path: root/src/lib/gpe_pba.c
blob: c3b0a00dcf407dc17a1c1d45778e5a343d837fbf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
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;
}
        
    
    
          
    

    
                     
    
                     
OpenPOWER on IntegriCloud