summaryrefslogtreecommitdiffstats
path: root/src/include/usr/targeting/attrrp.H
blob: cb7e9e35ef8cb5bafb963b2ada7702315029d517 (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
/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/include/usr/targeting/attrrp.H $                          */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2012,2018                        */
/* [+] 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 __TARGETING_ATTRRP_H
#define __TARGETING_ATTRRP_H

/**
 *  @file targeting/attrrp.H
 *
 *  @brief Interface for the attribute resource provider, which manages the
 *      memory associated with targeting attributes and provides any
 *      translation, if necessary
 */
//******************************************************************************
// Includes
//******************************************************************************

#include <vector>
#include <initservice/taskargs.H>
#include <sys/msg.h>
#include <targeting/adapters/types.H>
#include <targeting/common/targetservice.H>
#include <targeting/common/attributeTank.H>

namespace TARGETING
{

// Forward declaration of attribute section parsed information structure.
struct AttrRP_Section;

#ifdef __HOSTBOOT_RUNTIME
/**
 *  @brief Structure used to store Node specific information
 */
struct NodeInfo
{

    NodeInfo() :
        pTargetMap(nullptr),
        pSections(nullptr),
        sectionCount(0)
    {
    }

    // Pointer to the targeting image
    void*           pTargetMap;

    // Parsed structures of the attribute sections.
    AttrRP_Section* pSections;

    // Count of attribute sections.
    size_t          sectionCount;

};

/**
 *  @brief enumeration of node instance status
 */
enum NodeInstanceStatus
{
    SINGLE_NODE,
    MULTI_NODE,
    MULTI_NODE_LT_MAX_INSTANCES,
    MULTI_NODE_INSTANCE_GAP,
};
#endif

/**
 *  @class AttrRP
 *
 *  @brief Attribute Resource Provider daemon class.
 *
 *  @par Detailed Description:
 *      Provides all the functionality to translate between PNOR and
 *      Attribute virtual memory spaces.  Parses PNOR header for attribute
 *      sections, allocates virtual memory spaces with the kernel for each
 *      section, and handles virtual memory request messages from the
 *      kernel.
 */
class AttrRP
{

    // add some friends for the attribute sync features
#ifndef __HOSTBOOT_RUNTIME
    friend  bool TargetService::writeSectionData(
                           const std::vector<sectionRefData>& i_pages );

    friend  void TargetService::readSectionData(
                           std::vector<sectionRefData>& o_pages,
                           const SECTION_TYPE i_sectionId,
                           const TARGETING::NODE_ID i_nodeId);

#else
    friend errlHndl_t RT_TARG::saveRestoreAttrs(void *,
                                                void *,
                                                uint8_t);
#endif

    public:

        /**
         *  @brief Returns physical address of HB data reserved mem TOC
         *         note: does not unmap address
         *
         *  @return phys addr of table of contents of hb data reserved memory
         *
         */
        static uint64_t getHbDataTocAddr();

#ifdef __HOSTBOOT_RUNTIME
        /**
         *  @brief Initialize node struct for a given node
         *
         *  @param[in/out] io_nodeCont
         *      Node struct to be initialized
         *
         *  @param[in] i_header
         *      Targeting image header for node
         *
         *  @param[in] i_nodeId
         *      Node ID for which to initialize node struct
         *
         *  @return Error log
         */
        errlHndl_t nodeInfoInit(NodeInfo& io_nodeCont,
                                TargetingHeader* i_header,
                                const NODE_ID i_nodeId);

        /**
         *  @brief Returns address of targeting image in reserved memory
         *
         *  @param[in] i_nodeId
         *      Node ID for which to get targeting image address
         *
         *  @return Address of targeting image as a void*
         */
        void* getTargetMapPtr(const NODE_ID i_nodeId);
#endif

        /**
         *  @brief Returns base address of the RO section containing the
         *      targets
         *
         *  @param[in] i_nodeId
         *      Node ID to get base address for, ignored by Hostboot, which
         *      always gets base address of local node
         *
         *  @return Base address of the RO section containing the targets as
         *      a void*
         */
        void* getBaseAddress(const NODE_ID i_nodeId);

        /**
         *  @brief Returns Node Id of the Target handle passed
         *
         *  @param[in] i_pTarget
         *      Non-NULL Target handle for which node ID is required.
         *  @param[out] o_nodeId
         *      Node ID of the Target Handle requested. If Target not found
         *      the invalid node will be return in here.
         *
         *  @return void
         */
        void getNodeId(const Target* i_pTarget,
                       NODE_ID& o_nodeId) const;

        /**
         *  @brief Translates given address, according to the resource
         *      provider's translation algorithm
         *
         * @param[in] i_pAddress
         *     Address to translate
         *
         * @param[in] i_pTarget
         *     Node target used by common code, unused in Hostboot
         *
         * @return void* Returns the translated address.  Common attribute
         *     code has a static, compile time check that is used to
         *     determine whether to call this function, however the Hostboot
         *     compiler complains when this is not provided.  Therefore
         *     while this method exists, Hostboot will never call it, and if
         *     it does it will always get a no-op translation.
         */
        void* translateAddr(
            void* i_pAddress,
            const Target* i_pTarget)
#ifndef __HOSTBOOT_RUNTIME
        {
            return i_pAddress;
        }
#else
        ;
#endif

        /**
         *  @brief Translates given address, according to the resource
         *      provider's translation algorithm
         *
         * @param[in] i_pAddress
         *     Address to translate
         *
         * @param[in] i_nodeId
         *     Node ID used by common code, unused in Hostboot
         *
         * @return void* Returns the translated address.  Common attribute
         *     code has a static, compile time check that is used to
         *     determine whether to call this function, however the Hostboot
         *     compiler complains when this is not provided.  Therefore
         *     while this method exists, Hostboot will never call it, and if
         *     it does it will always get a no-op translation.
         */
        void* translateAddr(
            void* i_pAddress,
            const TARGETING::NODE_ID i_nodeId)
#ifndef __HOSTBOOT_RUNTIME
        {
            return i_pAddress;
        }
#else
        ;
#endif

        /**
         *  @brief Initializes and starts the AttrRP daemon.
         *
         *  @param[in/out] io_taskRetErrl
         *      Error log handle; on input, a NULL error log handle; on
         *      output, a NULL error log handle on success, or !NULL handle
         *      on failure
         *
         *  @note If any error occurs during initialization, it will be
         *        reported back through the TaskArgs structure to the init
         *        service.
         */
        static void init(errlHndl_t& io_taskRetErrl, bool i_isMpipl = false);

#ifndef __HOSTBOOT_RUNTIME
        /**
         *  @brief Copies all present attribute sections to memory.
         *
         *  @param[in,out] i_addr
         *      Physical address at the bottom of the desired region to
         *      place.
         *
         *  @return Virtual address to the region.
         */
        static void* save(uint64_t& io_addr);

        /**
         *  @brief Copies all present attribute sections to memory.
         *
         *  @param[in] i_dest
         *      Physical address to copy override data into
         *  @param[in,out] io_size
         *      in: Maximum size of allocated space in bytes
         *      out: Actual number of bytes used (zero means no overrides)
         *
         *  @return Error log
         */
        static errlHndl_t save(uint8_t * i_dest, size_t & io_size);

        /**
         *  @brief Returns size needed to save all attributes
         *
         *  HDAT requires up front knowledge of largest section
         *
         *
         *  @return Size of all attribute sections
         */
        static uint64_t  maxSize( );

        /**
         *  @brief Copies all present attribute override tanks to memory.
         *
         *  @param[in] i_dest
         *      Physical address to copy override data into
         *  @param[in,out] io_size
         *      in: Maximum size of allocated space in bytes
         *      out: Actual number of bytes used (zero means no overrides)
         *
         *  @return Error log
         */
        static errlHndl_t saveOverrides( uint8_t* i_dest,
                                         size_t& io_size );

#else
        /**
         *  @brief Get node instance status of attribute resource provider
         *  which indicates if the attribute resource provider is handling
         *  a single node or multiple nodes
         *
         *  @return Node instance status
         */
        NodeInstanceStatus getInstanceStatus()
        {
            return iv_instanceStatus;
        }

        /**
         *  @brief Get count of nodes handled by attribute resource provider.
         *
         *  @return Number of node containers
         */
        size_t getNodeCount()
        {
            return iv_nodeContainer.size();
        }
#endif

    protected:

        /**
         *  @brief Initialize the attribute resource provider
         *
         *  @par Detailed Description:
         *      Ensures member variables are initialized to sane values.
         */
        AttrRP()
#ifndef __HOSTBOOT_RUNTIME
            : iv_msgQ(NULL), iv_sections(NULL), iv_sectionCount(0),
              iv_isMpipl(false)
#else
            : iv_isTempInstance(false), iv_instanceStatus(SINGLE_NODE),
              iv_isMpipl(false)
#endif
        {
        };

#ifdef __HOSTBOOT_RUNTIME
        /**
         *  @brief Initialize temporary attribute resource provider
         *
         *  @par Detailed Description:
         *      Ensures member variables are initialized to sane values.
         */
        AttrRP(TargetingHeader* i_header,
               NODE_ID i_nodeId,
               size_t i_nodeCount,
               NodeInstanceStatus i_instanceStatus)
            : iv_isTempInstance(true), iv_instanceStatus(i_instanceStatus),
              iv_isMpipl(false)
        {
            // Work with nodes before passed in node
            for(NODE_ID l_nodeId = NODE0; l_nodeId < i_nodeCount; ++l_nodeId)
            {
                // Create local copy of container for node info struct
                NodeInfo l_nodeCont;

                if(l_nodeId == i_nodeId)
                {
                    // Initialize local copy of container for node info struct
                    errlHndl_t l_errl = nodeInfoInit(l_nodeCont,
                                                     i_header,
                                                     i_nodeId);
                    if (l_errl)
                    {
                        l_errl->setSev(ERRORLOG::ERRL_SEV_UNRECOVERABLE);

                        /* Commit the error */
                        errlCommit(l_errl, TARG_COMP_ID);

                        break;
                    }
                }

                // Push back node info struct into the node container
                iv_nodeContainer.push_back(l_nodeCont);
            }
        };
#endif

        /**
         *  @brief Destroy the attribute resource provider
         *
         *  @par Detailed Description:
         *      Frees any memory allocated by the resource provider.
         *
         *  @note This should never actually be used for the singleton
         *        instance because the daemon thread and the vmm blocks
         *        are unable to be reclaimed.  Function will assert if
         *        called due to leaky behavior.
         */
        ~AttrRP();

#ifndef __HOSTBOOT_RUNTIME
        /**
         *  @brief Copies the section data buffer from the vector to the
         *  appropriate section offset with respect to the node target ptr
         *  and section id.
         *
         *  @param[in] i_pages, vector of sectionRefData struct
         *
         *  @return true successful in writing Section Data
         *  @return false failed writing Section Data
         */

        bool writeSectionData(
                const std::vector <sectionRefData>& i_pages) const;

        /**
         *  @brief Populates the output vector with the correct information
         *         for the data pages specified by the selected section
         *
         *  @param[out] o_pages, vector of sectionRefData struct
         *  @param[in] i_sectionType
         *      Type of section to read
         *  @param[in] Node associated with the section, unused in HB
         *
         *  @return void
         */
        void readSectionData(
                  std::vector <sectionRefData>& o_pages,
            const SECTION_TYPE                  i_sectionType,
            const NODE_ID                       i_nodeId = 0) const;
#endif


    private:

        /**
         *  @brief Performs the startup of the daemon instance.
         *
         *  @par Detailed Description:
         *      init() is a static function that just calls
         *      Singleton<AttrRP>::instance().startup().  See init for
         *      behavior.
         *
         *  @param[in/out] io_taskRetErrl
         *      Error log handle; on input, a NULL error log handle; on
         *      output, a NULL error log handle on success, or !NULL handle
         *      on failure
         */
        void startup(errlHndl_t& io_taskRetErrl,  bool i_isMpipl = false);

#ifndef __HOSTBOOT_RUNTIME

        /**
         *  @brief Processes daemon messages
         *
         *  @par Detailed Description:
         *      Performs a while(1) waiting for messages from the
         *      kernel/VMM and handles as appropriately.  Reads / writes
         *      data from / to PNOR for the attribute sections.
         */
        void msgServiceTask() const;

        /**
         *  @brief Parses the attribute section header in PNOR.
         *
         *  @par Detailed Description:
         *      Constructs the local attribute section data structures
         *      (iv_sections / iv_sectionCount).
         *
         *  @return errlHndl_t
         *      Returns an error log handle that is NULL on success or !NULL
         *      on failure
         */
        errlHndl_t parseAttrSectHeader();

        /**
         *  @brief Allocates VMM sections for each Attribute section.
         *
         *  @par Detailed Description:
         *      Calls to the kernel to create VMM blocks for each attribute
         *      and initializes permissions appropriately based on section
         *      type.
         *
         *  @return errlHndl_t
         *      Returns an error log handle that is NULL on success or !NULL
         *      on failure
         */
        errlHndl_t createVmmSections();

        /**
        *  @brief Populates R/W and Heap Zero init sections of HBD from the
        *         values that we stored before we attempted the MPIPL
        *
        *  @par Detailed Description:
        *      Performs a memcpy from the physical address where HDAT information
        *      was stored by HBRT to the VMM addresses used by ATTR RP to look up
        *      attr values
        *
        *  @return void
        */
        void populateAttrsForMpipl(void);

        /** Internal implementation of save function. */
        void* _save(uint64_t&);

        /** Internal implementation of save function. */
        errlHndl_t _save(uint8_t* i_dest, size_t& io_size );

        /** Internal implementation of saveOverrides function. */
        errlHndl_t _saveOverrides( uint8_t* i_dest,
                                   size_t& io_size );

        /**
         * @brief Serialize and copy a single override tank out to memory
         *
         * @param[in]  i_dest  Starting address to copy data into
         * @param[inout] io_size  Input: Size of i_dest buffer
         *                        Output: Size of serialized data
         * @param[in]  i_tank  Override tank to serialize out
         * @param[in]  i_layer  Type of tank being worked on
         *
         * @return Error log
         */
        errlHndl_t saveOverrideTank( uint8_t* i_dest,
                                     size_t& io_size,
                                     AttributeTank* i_tank,
                                     AttributeTank::TankLayer i_layer );

        /**
         *  @brief Starts the attribute provider's message processor
         *
         *  @par Detailed Description:
         *      This function, being static, can be called from task_create
         *      and is used to enter the daemon thread's msgServiceTask
         *      loop to process messages.
         *
         *  @param[in] i_pInstance
         *      The AttrRP to call msgServiceTask on.
         */
        static void* startMsgServiceTask(void* i_pInstance);

        // Message Queue for VMM requests
        msg_q_t iv_msgQ;

        // Parsed structures of the attribute sections.
        AttrRP_Section* iv_sections;

        // Count of attribute sections.
        size_t iv_sectionCount;
#else
        // Indicator that AttrRP instance is a temporary one, not the singleton
        bool iv_isTempInstance;

        // Node Container
        std::vector<NodeInfo> iv_nodeContainer;

        // Node instance status
        NodeInstanceStatus iv_instanceStatus;
#endif

        bool iv_isMpipl;
};

/**
 *  @brief Give callers access to the singleton
 */
TARG_DECLARE_SINGLETON(TARGETING::AttrRP,theAttrRP);

extern const char* ATTRRP_MSG_Q;

// user-defined message subtype for MSG_MM_RP_RUNTIME_PREP
/** @enum msg_mm_rp_runtime_prep_t
  * @brief Message type and subtypes for the MSG_MM_RP_RUNTIME_PREP message
  */
enum msg_mm_rp_runtime_prep_t
{
    MSG_MM_RP_RUNTIME_PREP = 0x2, // prepare runtime for secure transition
                                  // of attrs
                                  // data[0] = MSG_MM_RP_RUNTIME_PREP_BEGIN or
                                  // data[0] = MSG_MM_RP_RUNTIME_PREP_END
    MSG_MM_RP_RUNTIME_PREP_BEGIN,
    MSG_MM_RP_RUNTIME_PREP_END,
};

} // End namespace TARGETING

#endif // __TARGETING_ATTRRP_H
OpenPOWER on IntegriCloud