summaryrefslogtreecommitdiffstats
path: root/src/usr/pore/poreve/porevesrc/pibmem.H
blob: 8e350284790281fa938cfca3f70aa551a1d7e500 (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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/pore/poreve/porevesrc/pibmem.H $                      */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* COPYRIGHT International Business Machines Corp. 2012,2014              */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
#ifndef __VSBE_PIBMEM_H
#define __VSBE_PIBMEM_H

// $Id: pibmem.H,v 1.3 2013/11/27 21:23:21 thi Exp $

/// \file pib2mem.H
/// \brief A model of the P8 "PIB-attached Memory"
///
/// PIBMEM is a PIB-attached memory that provides direct SCOM access to its
/// memory array starting at PIB local address 0, as well as indirect
/// addressing modes through control/data registers at offset 0x8000.
/// Addressing modes include simple indirect addressing as well as
/// configurable pre/post increment/decrement addressing.
///
/// Pibmem is derived from PibMemory - which provides the low-level
/// configuration and memory accesses.  This model extends PibMemory by the
/// addition of a set of control and status registers.
///
/// \todo Nail down why the spec. has separate error bits for illegal
/// addresses, and non-read(write)able addresses.

#include "bebits.H"
#include "bus.H"

namespace vsbe {
    
    class Pibmem;
    
    // PIBMEM register offsets

    const uint32_t PIBMEM_CONTROL_BASE = 0x8000;

    const uint32_t PIBMEM_CONTROL  = 0x8000;
    const uint32_t PIBMEM_ADDRESS  = 0x8001;
    const uint32_t PIBMEM_DATA     = 0x8002;
    const uint32_t PIBMEM_DATA_INC = 0x8003;
    const uint32_t PIBMEM_DATA_DEC = 0x8004;
    const uint32_t PIBMEM_STATUS   = 0x8005;
    const uint32_t PIBMEM_RESET    = 0x8006;
    const uint32_t PIBMEM_REPAIR   = 0x8007;

    /// The PIBMEM maps this many SCOM addresses, including its control space
    const uint32_t PIBMEM_PIB_SIZE = 0x8008;

    /// The value to write to control.reset_code to cause a reset.
    const uint32_t PIBMEM_RESET_CODE = 2;
    
    /// The encoding of the PIBMEM FSM idle state
    const uint32_t PIBMEM_FSM_IDLE = 0x40;


    /// The Pibmem control register controls auto inc/dec modes
    typedef union {
        uint64_t value;
        struct {
#ifdef _BIG_ENDIAN
            uint64_t auto_pre_increment : 1;
            uint64_t auto_post_decrement : 1;
            uint64_t reserved : 62;
#else 
            uint64_t reserved : 62;    
            uint64_t auto_post_decrement : 1;
            uint64_t auto_pre_increment : 1;
#endif
        } fields;
    } PibmemControl;

    const uint64_t PIBMEM_CONTROL_DEFINED = BE64_MASK(0, 1);


    /// The Pibmem address register only defines 16 address bits
    typedef union {
        uint64_t value;
        struct {
#ifdef _BIG_ENDIAN
            uint64_t reserved : 48;
            uint64_t address_pointer : 16;
#else 
            uint64_t address_pointer : 16;
            uint64_t reserved : 48;
#endif
        } fields;
    } PibmemAddress;

    const uint64_t PIBMEM_ADDRESS_DEFINED = BE64_MASK(48, 63);


    /// We model the PIBMEM status register, except for the ECC error bits and
    /// the FSM state (which always reports as IDLE in this model).  The
    /// status register is read-only, and only reset by a hard reset.
    typedef union {
        uint64_t value;
        struct {
#ifdef _BIG_ENDIAN
            uint64_t addr_invalid : 1;
            uint64_t write_invalid : 1;
            uint64_t read_invalid : 1;
            uint64_t ecc_uncorrected_error : 1;
            uint64_t ecc_corrected_error : 1;
            uint64_t bad_array_address : 1;
            uint64_t reserved0 : 5;
            uint64_t fsm_present_state : 7;
            uint64_t reserved1 : 46;
#else 
            uint64_t reserved1 : 46;
            uint64_t fsm_present_state : 7;
            uint64_t reserved0 : 5;
            uint64_t bad_array_address : 1;
            uint64_t ecc_corrected_error : 1;
            uint64_t ecc_uncorrected_error : 1;
            uint64_t read_invalid : 1;
            uint64_t write_invalid : 1;
            uint64_t addr_invalid : 1;
#endif
        } fields;
    } PibmemStatus;


    /// The 'reset_code' must be written with 0b10 to reset the memory
    typedef union {
        uint64_t value;
        struct {
#ifdef _BIG_ENDIAN
            uint64_t reset_code : 2;
            uint64_t reserved1 : 62;
#else 
            uint64_t reserved : 62;
            uint64_t reset_code : 2;
#endif
        } fields;
    } PibmemReset;

    const uint64_t PIBMEM_RESET_DEFINED = BE64_MASK(0, 1);
}


class
vsbe::Pibmem : public PibMemory {

public:

    ////////////////////////////// Creators //////////////////////////////

    /// Pibmem constructor
    ///
    /// \param[in] i_memorySize The maximum size of the memory in units of
    /// 8-byte doublewords.
    Pibmem(const size_t i_memorySize);

    virtual ~Pibmem();


    //////////////////////////// Manipulators ////////////////////////////

    /// Pibmem operation
    ///
    /// \param[in,out] io_transaction A PIB transaction object
    ///
    /// Read/write of addresses below the control range are direct SCOM access
    /// to the PIBMEM memory itself.  Indirect accesses use the indirect
    /// address and data register. 
    ///
    /// \retval rc A fapi::ReturnCode denoting success or a problem.
    fapi::ReturnCode
    operation(Transaction& io_transaction);


    //////////////////// Implementation  //////////////////////////////////

protected:

    /// Implements the PIBMEM reset sequence - all state is cleared
    void reset();

    /// Pibmem memory read/write operation
    ///
    /// \param[in,out] io_transaction A PIB transaction object
    ///
    /// \param[in] i_direct Indicates whether this is a direct or indirect
    /// access (for error reporting).  For indirect access the address comes
    /// from the address register.
    ///
    /// \retval rc A fapi::ReturnCode denoting success or a problem.
    fapi::ReturnCode memoryOperation(Transaction& io_transaction, 
                                     const bool i_direct);

    /// Increment/decrement the indirect address register
    ///
    /// \param[in] i_incr The (signed) increment/decrement
    void incrAddress(const int i_incr);

    /// The size of the memory in units of 8-byte doublewords
    uint32_t iv_memorySize;

    // Control/status register state.  Data registers have no substructure.

    PibmemControl iv_control;
    PibmemAddress iv_address;
    PibmemStatus iv_status;
    PibmemReset iv_reset;

    uint64_t iv_data, iv_dataInc, iv_dataDec, iv_repair;


    ///////////////////////////// Safety //////////////////////////////////

private:
    Pibmem(const Pibmem& rhs);
    Pibmem& operator=(const Pibmem& rhs);
};

/* Local Variables: */
/* c-basic-offset: 4 */
/* End: */

#endif  // __VSBE_PIBMEM_H
OpenPOWER on IntegriCloud