summaryrefslogtreecommitdiffstats
path: root/src/usr/hdat/hdatmsarea.H
blob: 83236d134eb353985eb03876bbb57cc459590d81 (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
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/hdat/hdatmsarea.H $                                   */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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 HDATMSAREA_H
#define HDATMSAREA_H
 
/**
 *  @file hdatmsarea.H
 *
 *  @brief This file contains the class definition for the mainstore areas.
 *         This structure is part of the larger mainstore VPD structure
 *         which describes the various chips which make up the memory subsystem.
 *
 */

/*----------------------------------------------------------------------------*/
/* Includes                                                                   */
/*----------------------------------------------------------------------------*/
#include <stdint.h>              // standard types
#include <hdat/hdat.H>                // HDAT header type definitions
#include "hdathdif.H"            // HdatHdif base class definition
#include "hdatram.H"             // HdatRam class definition
#include <errl/errlentry.H>      // ErrlEntry class
#include "hdatutil.H"

namespace HDAT
{

/*----------------------------------------------------------------------------*/
/* Constants                                                                  */
/*----------------------------------------------------------------------------*/

const uint16_t HDAT_MS_AREA_VERSION = 0x50;
const char HDAT_MSAREA_STRUCT_NAME[] = "MSAREA";

/** @brief Since the size of each MS Area must the same as all others, the
 *         total size of the EC level array and the address range array must
 *         be the same in each MS area.  The constants below are the result of
 *         a bug found during initial PHYP bringup when several MS areas were
 *         built with different sizes.  We always reserve enough space for the
 *         maximum number of array entries since we don't know in advance how
 *         many entries will actually be added.
 */
const uint32_t HDAT_MAX_EC_ENTRIES = 5;
const uint32_t HDAT_MAX_ADDR_RNG_ENTRIES = 4;

 /** @enum hdatDataPtrs
 *  Constants for the internal data pointers that are added to the base class
 */
enum hdatMsAreaDataPtrs
{
    HDAT_MS_AREA_FRU_ID    =  0,
    HDAT_MS_AREA_KWD       =  1,
    HDAT_MS_AREA_ID        =  2,
    HDAT_MS_AREA_SIZE      =  3,
    HDAT_MS_AREA_ADDR_RNG  =  4,
    HDAT_MS_AREA_AFF       =  5,
    HDAT_MS_AREA_EC_ARRAY  =  6,
    HDAT_MS_AREA_HOST_I2C  =  7,
    HDAT_MS_AREA_RESERVED1 =  8,
    HDAT_MS_AREA_RESERVED2 =  9,
    HDAT_MS_AREA_RESERVED3 = 10,
    HDAT_MS_AREA_LAST      = 11
};

 
/*----------------------------------------------------------------------------*/
/* Typedefs                                                                   */
/*----------------------------------------------------------------------------*/

/** @brief Structure definition for the main store area id and status.
    Reserved bytes are added to make the structure a multiple of 4 bytes.
    Adjust the reserved size as necessary if new members are added to this
    structure.
 */
struct hdatMsAreaId_t
{
    uint16_t hdatMsAreaId;       // 0x0000 Identifier for this mainstore area
    uint16_t hdatMsAreaParentType; // 0x0002 Memory parent type
    uint16_t hdatMsAreaStatus;   // 0x0004 Status
    uint16_t hdatInterleavedId;  // 0x0006 Id for MS areas which are interleaved
    uint32_t hdatFsiDevicePathLen; // 0x0008 FSI Device Path – Actual Length
    uint8_t  hdatFsiDevicePath[64];// 0x000C FSI Device Path
}  __attribute__ ((packed));


/** @brief Structure definition for the size of the main store area
 */
struct hdatMsAreaSize_t
{
    uint32_t hdatReserved1;  // 0x0000 Reserved to make hdatMsAreaSize 8 bytes
                             // in future
    uint32_t hdatMsAreaSize; // 0x0004 Total size of the configured main store
                             // in mega-bytes
}  __attribute__ ((packed));

/** @brief Structure definition for Selective Memory Mirroring attributes field
 */
struct hdatSMMAttributes_t
{
    uint8_t hdatRangeIsMirrorable;  // 0x0000 Memory range is mirrorable
    uint8_t hdatMirroringAlgorithm; // 0x0001 Hardware mirroring algorithm to
                                      // use
    uint8_t hdatIsSMFmemory;        // 0x0002 SMF memory region
    uint8_t hdatReserved;           // 0x0003
}  __attribute__ ((packed));


/** @brief Structure definition for an array of main store area address ranges
 */
struct hdatMsAreaAddrRange_t
{
    hdatMsAddr_t hdatMsAreaStrAddr;   // 0x0000 Range starting address
    hdatMsAddr_t hdatMsAreaEndAddr;   // 0x0008 Range ending address+1
    uint32_t     hatMsAreaProcChipId; // 0x0010 Processor physical chip id
                                      // associated with this address range
    hdatSMMAttributes_t hdatSMMAttributes; // 0x0014 SMM Attributes
    hdatMsAddr_t      hdatStartMirrAddr;   // 0x0018 Starting Mirrorable Address
                                          // for range
    uint32_t     hdatMsAreaMemCntId;  // 0x0020 Memory Controller ID
}  __attribute__ ((packed));


/** @brief Structure definition for the processor affinity
 */
struct hdatMsAreaAffinity_t
{
    uint32_t hdatMsAreaModuleId;   // 0x0000 Processor Module ID associated
                                   //        with this mainstore area
    uint32_t hdatMsAffinityDomain; // 0x0004 Affinity Domain
}  __attribute__ ((packed));


/*----------------------------------------------------------------------------*/
/* Constants                                                                  */
/*----------------------------------------------------------------------------*/

/** @enum hdatMsAreaChildPtrs
 *        Constants for the child structure pointers that are added to the base
 *        class
 */
enum hdatMsAreaChildPtrs
{
    HDAT_MS_AREA_RAM_AREAS       = 0,
    HDAT_MS_AREA_CHILD_RESERVED1 = 1,
    HDAT_MS_AREA_CHILD_LAST      = 2
};


/*----------------------------------------------------------------------------*/
/* C++ class definition                                                       */
/*----------------------------------------------------------------------------*/

/** Begin Class Description                                                 
 *
 * @brief  The HdatMsArea class is used to construct objects which describe
 *         main store areas.  
 *
 * Description: This class defines a specialized object.  It is not intended
 *              that anyone can create an object of this type.  In particular,
 *              the object is built only in the hdatstep process when the step
 *              that builds hypervisor data structures is run.
 *
 *          The real purpose of the object is to create the various main store
 *          area structures as defined by the PHYP Initialization architecture
 *          This data structure is eventually DMA'd to main memory.  The
 *          class is not defined to be a general purpose interface for
 *          building this object by anyone other than the hdatstep process.
 *
 * Thread safety:  An HdatMsArea object is not thread safe.  That is, a single
 *                 object cannot be shared and used concurrently by
 *                 multiple threads at the same time.  An object can be used by 
 *                 multiple threads if the threads serialize access.  And of
 *                 course, each thread can use its own object with no concerns
 *                 about what other threads are doing.
 *
 * Signal handler usage: This class is not intended to be used in a signal 
 * handler and nothing has been done to try and make it safe to use
 * in a signal handler.
 *                                             
 * End Class Description
 */
class HdatMsArea : public HdatHdif
{
public:

  /** 
   * @brief Construct an HdatMsArea object.
   *
   *       This is the constructor for the HdatMsArea object.  
   *
   *       If you are constructing this object on the heap by using new, then
   *       you must check the pointer returned from new to see if it is null.
   *       If it is null, new failed to allocate storage and the constructor
   *       was not called.  If it is not null, then you must check o_errlHndl
   *       to see if the constructor ran successfully.  If o_errlHndl indicates
   *       an error was reported by the constructor, new has already allocated
   *       heap storage and the object must be deleted in order to free the
   *       heap storage.
   *
   * @pre None
   *
   * @post An HdatMsArea object has been constructed.  
   *     Heap storage has been allocated.
   *
   * @param[out] o_errlHndl - If any errors occur, the HdatMsArea object
   *                       is NOT constructed and errors are returned in this
   *                       parameter
   * @param[in]i_msAreaId  - input parameter - A unique id for each main store
   *                       area associated with a mainstore VPD object.  The id
   *                       starts at 0 and is incremented by 1 for each new
   *                       mainstore area.
   * @param[in] i_ramCnt - The number of RAM objects that will be
   *                      added to the mainstore area.  If an exact count cannot
   *                      be computed, a maximum number can be provided.
   * @param[in] i_chipEcCnt - The number of EC entries that will be
   *                       added to the mainstore area.  If an exact count
   *                       cannot be computed, a maximum number can be provided.
   * @param[in] i_addrRngCnt  - The number of address range entries that
   *                        will be added to the mainstore area.  If an exact
   *                        count cannot be computed, a maximum number can be 
   *                        provided.
   * @param[in] i_resourceId - The FRU's resource id
   * @param[in] i_slcaIdx   - SLCA index for this FRU (only meaningful
   *                        if keyword size > 0).
   * @param[in] i_kwdSize   - Size of the ASCII keyword data if available,
   *                        otherwise 0.
   * @param[in] i_kwd       - ASCII keyword data if available, otherwise
   *                        NULL.
   *
   * @return A null error log handle if successful, else the return code point 
   *         to by o_errlHndl contains one of:
   *
   * @retval HDAT_ALLOC_ERROR
   */
    HdatMsArea(errlHndl_t &o_errlHndl,
             TARGETING::Target* i_target,
             uint16_t i_msAreaId,
             uint32_t i_ramCnt,
             uint32_t i_chipEcCnt,
             uint32_t i_addrRngCnt,
             uint32_t i_resourceId,
             uint32_t i_slcaIdx,
             uint32_t i_kwdSize,
             char *&i_kwd);


  /**
   * @brief HdatMsArea object destructor
   *
   *        This is the destructor for an HdatMsArea object.  Any heap storage
   *        allocated for the object is dallocated.
   *
   * @pre No preconditions exist
   *
   * @post The HdatMsArea object has been destroyed and can no longer be used.
   *
   */
    virtual ~HdatMsArea();


  /**
   * @brief Add a RAM area to this main store area
   *
   *       A RAM object is added.
   *
   * @pre The number of RAM objects added cannot exceed the RAM count specified
   *      on the HdatMsArea constructor
   *
   * @post None
   *
   * @param[in] i_ram - input parameter - A RAM object
   *
   * @return A null error log handle if successful, else the return code pointed
   *         to by o_errlHndl contains one of:
   *
   * @retval HDAT_ARRAY_ERROR
   */
    errlHndl_t addRam(HdatRam &i_ram);


  /**
   * @brief Update the mainstore area to specify the type of memory.
   *
   * @pre None
   *
   * @post None
   *
   * @param[in] i_type - input parameter - This specifies the type of memory
   *               card  for this mainstore area.
   */
    void setParentType(uint16_t i_type);


  /**
   * @brief Update the mainstore area to specify the status of the memory DIMMS
   *
   * @pre None
   *
   * @post None
   *
   * @param[in] i_status - input parameter - See the hdatMsAreaStatus enum.
   *    The value specified here can be a bitwise OR of the enum values.
   */
    void setStatus(uint16_t i_status);


  /**
   * @brief Update the mainstore area with a unique ID for interleaved areas
   *
   *        The call to setStatus must also turn on the HDAT_MEM_SHARED flag.
   *
   * @pre None
   *
   * @post None
   *
   * @param[in] i_status - A unique ID. All MS areas which are
   *                   interleaved will have the same ID.
   */
    void setInterleavedId(uint16_t i_id);


  /** 
   * @brief Update the mainstore area to specify the total size of the mainstore
   *        area.
   *
   * @pre None
   *
   * @post None
   *            
   * @param[in] i_size - The total size of the configured mainstore
   *             area in megabytes.  It is the (high address of the mainstore
   *             area + 1 minus the low address of the mainstore area) divided
   *             by 1 megabyte.
   */
    void setSize(uint32_t i_size);


  /**
   * @brief Update the mainstore area to specify associated processor id
   *
   * @pre None
   *
   * @post None
   *               
   * @param[in] i_moduleId - The Module Id of the processor
   *                     associated with this mainstore area.
   */
    void setModuleId(uint32_t i_moduleId);

  /**
   * @brief Update the mainstore area to specify its affinity domain
   *
   * @pre None
   *
   * @post None
   *
   * @param[in] i_affinityDomain - The Affinity Domain
   *                           associated with this mainstore area. 
   */
    void setAffinityDomain(uint32_t i_affinityDomain);

  /**
   * @brief Get the SLCA index, the keyword size, and the ASCII keyword
   *
   * @pre None
   *
   * @post None
   *
   * @param[out] o_resourceId - The resource ID for this FRU
   * @param[out] o_slcaIdx - The SLCA index for this FRU
   * @param[out] o_kwdSize The size of the ASCII keyword data
   * @param[out] o_kwd -  A pointer to the ASCII keyword
   *
   */
    void getKwdInfo(uint32_t &o_resourceId,
                  uint32_t &o_slcaIdx,
                  uint32_t &o_kwdSize,
                  char *&o_kwd);


  /**
   * @brief Update the mainstore area to specify a memory address range.
   *        More than one address range can be added.
   *
   * @pre One cannot add any more address range entries than was specified by
   *      the i_addrRngCnt parameter on the HdatMsArea constructor.
   *
   * @post An address range entry has been added.
   *
   * @param[in] i_start      - The starting address of the range
   * @param[in] i_end        - The ending address of the range + 1
   * @param[in] i_procChipId - which is the chip id of the physical processor
   * @param[in] i_rangeIsMirrorable - Specifies whether the range is
   *                              mirrorable
   * @param[in] i_mirroringAlgorithm - Specifies hardware mirroring
   *                               algorithm to use
   * @param[in] i_startMirrAddr - Specifies the starting mirrorable
   *                          address for range
   * @param[in] i_memcntlrId - Memory Controller ID
   * @param[in] i_hdatSmf - Whether the range is in SMF memory
   *
   * @return A null error log handle if successful, else the return code pointed
   *         to by o_errlHndl contains one of:
   *
   * @retval HDAT_ARRAY_ERROR
   */
  errlHndl_t addAddrRange(hdatMsAddr_t &i_start,
                          hdatMsAddr_t &i_end,
                          uint32_t i_procChipId,
                          bool i_rangeIsMirrorable,
                          uint8_t i_mirroringAlgorithm,
                          hdatMsAddr_t &i_startMirrAddr,
                          uint32_t  i_memcntlrId,
                          bool i_hdatSmf);


  /**
   * @brief Add engineering change information for memory interface chips
   *
   * @pre The first EC entry added must be for the memory controller
   *
   * @post One cannot add any more engineering change entries than was specified
   *  by the i_chipEcCnt parameter on the HdatMsArea constructor.
   *
   * @param[in] i_manfId - input parameter - Chip's manufacturing id
   * @param[in] i_ecLvl  - input parameter - Chip's engineering change level
   *
   * @return A null error log handle if successful, else the return code pointed
   *         to by o_errlHndl contains one of:
   *
   * @retval HDAT_ARRAY_ERROR
   */
    errlHndl_t addEcEntry(uint32_t i_manfId,
                        uint32_t i_ecLvl);

   /** 
    * @brief Update the Host I2C device info
    *
    * @pre None
    *
    * @post None
    *               
    * @param i_I2cDevEntries - input parameter - This contains I2C master infoi,
    *     I2C slave device type and I2C device purpose
    *
    * @retval void         
    */
   void setMsaI2cInfo (
       std::vector<hdatI2cData_t>& i_I2cDevEntries );

  /**
   * @brief This routine returns the length of all RAM objects associated
   *        with this mainstore area
   *
   * @pre None
   *
   * @post None
   *
   */
    uint32_t ramObjSizes();


  /**
   * @brief This routine finalizes the object's size and updates header
   * information
   *
   *
   * @pre All data must have been added to the object and it must be ready to
   *      commit.
   *
   * @post This method must be called first before the inherited size() method
   *       can be called and return correct results.
   *
   */
  void finalizeObjSize();


  /**
   * @brief Print an HdatMsArea object.
   *
   *     This method is a debug mthod which prints out a mainstore area object.
   *    
   * @pre None
   *
   * @post None
   *
   */
  void prt();

  /**
   * @brief Get MS area size
   *
   *       This method is to retreive complete MS area size
   *
   * @pre None
   *
   * @post None
   *
   * @return - returns size value
   *
   */
    uint32_t  getMsAreaSize();

  /**
   * @brief Get Ram area size
   *
   *       This method invokes ram getSize routine for all the child pointers
   *       and gets the size.
   *
   * @pre None
   *
   * @post None
   *
   * @return - returns size value
   *
   */
    uint32_t getRamAreaSize();
  /**
   * @brief Writes the MS area data in main store memory
   *
   * @pre None
   *
   * @post None
   *
   * @param[inout] i_data - memory used to write the data
   *
   *
   */
    void commit(UtilMem &i_data);
  /**
   * @brief Iterates all the child pointers to invoke function that writes ram
   * area data
   *
   * @pre None
   *
   * @post None
   *
   * @param[inout] i_data - memory used to write the data
   *
   *
   */
    void commitRamAreas(UtilMem &i_data);
private:


    /** Object Instance Data
     *
     * @li iv_kwdSize         - size of the ASCII keyword
     * @li iv_maxAddrRngCnt   - maximum number of address range entries that
     *                          can be added
     * @li iv_maxEcCnt        - maximum number of EC entries that can be added
     * @li iv_msaHostI2cCnt   - actual number of host I2C entries that can be
     *                          added
     * @li iv_msaHostI2cSize  - total size of host i2c data
     * @li iv_maxRamCnt       - maximum number of RAM objects that can be added
     * @li iv_actRamCnt       - actual number of RAM objects that were added
     * @li iv_maxRamObjSize   - maximum size of any RAM object associated with
     *                          this mainstore area
     * @li iv_kwd             - ptr to storage which holds the ASCII keyword
     * @li iv_ramPadReq       - padding will be required for one or more RAM
     *                          objects to make them all the same size
     * @li iv_fru             - FRU Id information
     * @li iv_msId            - mainstore area id information
     * @li iv_msSize          - mainstore size information
     * @li iv_AddrRngArrayHdr - data array header
     * @li iv_addrRange       - mainstore addresses
     * @li iv_aff             - CPU affinity information
     * @li iv_ecArrayHdr      - data array header
     * @li iv_ecLvl           - EC level array
     * @li iv_msaI2cHdr       - Host I2C info header
     * @li iv_msaI2cEntryPtr - Host I2C info entries
     * @li iv_ramPtrs         - ptr to storage which contains one of more ptrs
     *                          to RAM objects
     */
    uint32_t                     iv_kwdSize;
    uint32_t                     iv_maxAddrRngCnt;
    uint32_t                     iv_maxEcCnt;
    uint32_t                     iv_msaHostI2cCnt;
    uint32_t                     iv_msaHostI2cSize;
    uint32_t                     iv_maxRamCnt;
    uint32_t                     iv_actRamCnt;
    uint32_t                     iv_maxRamObjSize;
    char                        *iv_kwd;
    bool                         iv_ramPadReq;
    hdatFruId_t                  iv_fru;
    hdatMsAreaId_t               iv_msId;
    hdatMsAreaSize_t             iv_msSize;
    hdatHDIFDataArray_t          iv_addrRngArrayHdr;
    hdatMsAreaAddrRange_t        *iv_addrRange;
    hdatMsAreaAffinity_t         iv_aff;
    hdatHDIFDataArray_t          iv_ecArrayHdr;
    hdatEcLvl_t           *iv_ecLvl;
    hdatHDIFVersionedDataArray_t iv_msaI2cHdr;
    uint8_t                     *iv_msaI2cDataPtr;
    HdatRam                    **iv_ramPtrs;


    /** Class (static) Data
     *
     * Only one copy of this data exists in a process.
     *
     * @li cv_actualCnt - a count of how many HdatMsArea objects are created
     */
    static uint32_t   cv_actualCnt;

}; // end of HdatMsArea class

}
#endif // HDATMSAREA_H
OpenPOWER on IntegriCloud