summaryrefslogtreecommitdiffstats
path: root/src/include/usr/targeting/common/targetservice.H
blob: 82001c0ae9a282b8a0d41f96c5c45bcde53243dd (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
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/include/usr/targeting/common/targetservice.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_COMMON_TARGETSERVICE_H
#define __TARGETING_COMMON_TARGETSERVICE_H

/**
 *  @file targeting/common/targetservice.H
 *
 *  @brief Interface for the target service
 *
 *  This header file contains the interface definition for the target service
 *  which is responsible for configuring and aggregating the pool of valid
 *  targets, and providing services to access targets based on various criteria
 */

//******************************************************************************
// Includes
//******************************************************************************

// STD
#include <stdint.h>
#include <stdlib.h>
#include <vector>

// This component
#include <targeting/common/attributes.H>
#include <attributetraits.H>
#include <targeting/common/iterators/iterators.H>
#include <targeting/common/predicates/predicates.H>
#include <targeting/adapters/types.H>
#include <targeting/common/error.H>
#include <pnortargeting.H>

//******************************************************************************
// Interface Definitions
//******************************************************************************

//******************************************************************************
// Method to access the targeting service externally
//******************************************************************************

namespace TARGETING
{
    // Forward declaration of attribute resource provider class.
    class AttrRP;

    class TargetService;

    /*
     * @brief -  typedef for node Id
     */
    typedef uint8_t NODE_ID;

    /* Node 0 */
    static const NODE_ID NODE0 = 0x00;

    /* Invalid Node Id  - to initialize struct variable*/
    static const NODE_ID INVALID_NODE = 0xFF;

    /* Invalid Section Id - to initialize struct variable */
    static const uint8_t INVALID_SECTIONID  = 0xFF;

    // Special "not found" fabric group ID is the data type with all bits set
    static const ATTR_FABRIC_GROUP_ID_type FABRIC_GROUP_ID_NOT_FOUND =
        INVALID_NODE;

    /**
     *  @brief Struct specifying different parameters required for section data
     *  update on the sectionId/NodePtr.
     *
     *  Given a struct with the following elements required to point to a
     *  specific section in a given node and the dataPtr to be updated.
     *  Size of the data is always the Page size i.e. 4K
     *
     *  Struct element details -
     *  sectionId - Section Id
     *  nodeId  - Node Id
     *  pageNumber - PageNumber for the section.
     *  dataPtr - Data Ptr
     *  pNodeTarget - Node Targeting Ptr
     *
     */

    struct sectionRefData
    {
        sectionRefData() :
            sectionId(0x00),
            nodeId(INVALID_NODE),
            pageNumber(0),
            dataPtr(NULL),
            pNodeTarget(NULL)
        {
        }

        uint8_t  sectionId;
        uint8_t  nodeId;
        uint16_t  pageNumber;
        uint8_t* dataPtr;
        Target*  pNodeTarget;
    };


    /**
     *  @brief Returns a reference to the targeting service singleton
     *
     *  @return Reference to the targeting service
     */
    TARGETING::TargetService& targetService();

/**
 *  @brief Sentinel representing the master processor chip target early in
 *      host boot prior to initialization of the target service.  Needed by the
 *      DD framework to bring PNOR device driver online.  Note this target
 *      cannot be used as input to any target service APIs.
 */
extern Target* const MASTER_PROCESSOR_CHIP_TARGET_SENTINEL;

/**
 *  @brief TargetService class
 *
 *  This class manages the set of possible targets and provides facility to
 *  access specific targets, based on given criteria
 */
class TargetService
{
    public:

        /**
         *  @brief Enum specifying the recursion depth for target searching
         *
         *  Indicates whether to return only IMMEDIATE children/parent of a
         *  target, or ALL children/parents of a target
         */
        enum RECURSION_LEVEL
        {
            IMMEDIATE = 0x01, ///< Return immediate children/parent of a target
            ALL       = 0x02, ///< Return all children/parents of a target
        };

        /**
         *  @brief Enum specifying the type of association between targets
         *
         *  Indicates what relationship the result target should have to the
         *  target in question
         */
        enum ASSOCIATION_TYPE
        {
            PARENT,             ///< The result target(s) should be parents by
                                ///< containment
            CHILD,              ///< The result target(s) should be children by
                                ///< containment
            PARENT_BY_AFFINITY, ///< The result target(s) should be the parents
                                ///< by hardware affinity
            CHILD_BY_AFFINITY,  ///< The result target(s) should be children by
                                ///< Hardware affinity.  For example the child
                                ///< of a memory controller channel target might
                                ///< be a DIMM target
            PERVASIVE_CHILD,    ///< The result target(s) should be units
                                ///< associated with a pervasive target
            PARENT_PERVASIVE,   ///< The result target should be a pervasive
                                ///< target
            MAX_ASSOCIATION_TYPES, ///< Number of types, must always be last
        };

    public:

        /**
         *  @brief Construct the target service
         *
         *  Constructs the target service, but does not actually initialize the
         *  target pool
         *
         *  @post Target service instantiated, but target pool not initialized
         */
        TargetService();

        /**
         *  @brief Destroys the target service
         *
         *  Destroys the target service; it should never be run since it hides
         *  behind a singleton, but is included for completeness
         *
         *  @post Target service is destroyed, and all owned resources are
         *      reclaimed
         */
        ~TargetService();

        /**
         *  @brief Initializes the target service
         *
         *  @par Detailed Description:
         *  Initializes the target service, including determining maximum number
         *  of targets, setting up the target pool, etc. for each node in the
         *  system blueprint local to the subsystem. Should be called once PNOR
         *  is accessible and can be mapped
         *
         *  @param[in] i_maxNodes, max number of nodes to initialize within the
         *      targetservice.
         *
         *  @pre N/A
         *
         *  @post Target service initialized with all possible targets. User
         *      would need to call targetservice().initDefaultMasterNode to make
         *      targetservice fully initialized and ready to be used.
         */
        void init(const size_t i_maxNodes = 1);

        /**
         *  @brief Returns whether target service has initialized or not
         *
         *  @return bool indicating whether service has initialized or not
         *  @retval true Service has initialized and can be used
         *  @retval false Service has not initializated and should not be used
         *      (other than to run the initialization)
         */
        bool isInitialized() const
        {
            return iv_initialized;
        }

        /**
         *  @brief Map iterator types to common aliases
         */
        typedef TargetIterator         iterator;
        typedef ConstTargetIterator    const_iterator;
        typedef TargetRawIterator      rawiterator;
        typedef ConstTargetRawIterator const_rawiterator;

        /**
         *  @brief Return iterator which points to first target service target
         *      (or end() if none)
         *
         *  @return Iterator pointing to first target service target
         */
        iterator begin();

#ifdef __HOSTBOOT_RUNTIME
        /**
         *  @brief Return iterator which points to first target service target
         *      (or end() if none) for a specific node
         *
         *  @param[in] i_nodeId, node Id
         *
         *  @return Iterator pointing to first target service target for node
         */
        iterator begin(NODE_ID i_nodeId);
#endif

        /**
         *  @brief Return rawiterator which points to first target service
         *      target (or end() if none)
         *
         *  @return RawIterator pointing to first target service target
         */
        rawiterator raw_begin();

        /**
         *  @brief Return iterator to const which points to first target service
         *      target (or end() if none)
         *
         *  @return Iterator to const pointing to first target service target
         */
        const_iterator begin() const;

        /**
         *  @brief Return rawiterator to const which points to first target
         *      service target (or end() if none)
         *
         *  @return RawIterator to const pointing to first target service target
         */
        const_rawiterator raw_begin() const;

        /**
         *  @brief Return iterator which points to the "past the end of the
         *      list" target maintained by the target service
         *
         *  @return Iterator pointing to the "past the end of the list" target
         *      maintained by the target service
         */
        iterator end();

        /**
         *  @brief Return rawiterator which points to the "past the end of the
         *      list" target maintained by the target service
         *
         *  @return RawIterator pointing to the "past the end of the list"
         *      target maintained by the target service
         */
        rawiterator raw_end();

        /**
         *  @brief Return iterator to const which points to the "past the end of
         *      the list" target maintained by the target service
         *
         *  @return Iterator to const pointing to the "past the end of the list"
         *      target maintained by the target service
         */
        const_iterator end() const;

        /**
         *  @brief Return rawiterator to const which points to the "past the end
         *      of the list" target maintained by the target service
         *
         *  @return RawIterator to const pointing to the "past the end of the
         *      list" target maintained by the target service
         */
        const_rawiterator raw_end() const;

        /**
         *  @brief Allow iterator access to the target service's target store
         */
        friend class _TargetIterator<Target*>;
        friend class _TargetIterator<const Target*>;

        /**
         *  @brief Allow rawiterator access to the target service's target store
         */
        friend class _TargetRawIterator<Target*>;
        friend class _TargetRawIterator<const Target*>;

        /**
         *  @brief Returns the top level physical target
         *
         *  Returns the top level (usually system) target.  Caller must check
         *  for a NULL top level target
         *
         *  @param[out] o_targetHandle Top level target handle
         *
         *  @pre N/A
         *
         *  @post The returned handle is NULL if a top level target doesn't
         *      exist or service not initialized, otherwise it references a
         *      valid top level target
         */
        void getTopLevelTarget(
            Target*& o_targetHandle) const;

        /**
         *  @brief Returns whether specified entity path corresponds to a real
         *      target
         *
         *  Consults the specified entity path and searches through all
         *  available targets to find a matching entity path attribute.  If it
         *  finds a match, then the associated target exists, otherwise it does
         *  not exist
         *
         *  @param[in] i_entityPath Entity path to verify for existence
         *  @param[out] o_exists Whether the entity path corresponds to a
         *      target
         *
         *  @pre N/A
         *
         *  @post "true" returned to caller if specified entity path exists,
         *      "false" if not or service not initialized
         */
        void exists(
            const EntityPath& i_entityPath,
                  bool&       o_exists) const;

        /**
         *  @brief Returns a target handle which has an associated entity path
         *      matching the specified entity path
         *
         *  Returns a target handle which has an associated entity path
         *  matching the specified entity path.  Caller must check the
         *  returned handle for NULL.
         *
         *  @param[in] i_entityPath Entity path for which to find the matching
         *      target handle
         *
         *  @pre N/A
         *
         *  @post NULL returned to caller if no match was found or service
         *      not initialized, otherwise a valid handle returned
         *
         *  @return Target handle
         *
         *  @retval NULL No target match found
         *  @retval !NULL Handle to the corresponding target
         */
        Target* toTarget(
            const EntityPath& i_entityPath) const;

        /**
         *  @brief Returns the master processor chip target handle
         *
         *  Returns the master processor chip target handle.  On systems
         *  without an alternate master, it returns a handle to the only master,
         *  if found (NULL otherwise).  On systems with multiple potential
         *  masters, it returns a target handle to the acting master (NULL
         *  otherwise).  If targeting information is not yet accessible (very
         *  early in the host boot IPL), the returned target handle will be a
         *  sentinel value representing the master (whichever it may be)
         *
         *  @param[out] o_masterProcChipTarget Target handle referring to the
         *      current master processor chip (the one connected to PNOR)
         *  @param[in]  i_pNodeTarget
         *      Handle to the node target to search for the acting master
         *      processor.  If NULL, HB will search whatever node it's
         *      running on, and FSP will search the physical drawer containing
         *      the lowest ordered fabric node ID.         *
         *  @pre Target Service must be initialized
         *
         *  @post Master processor chip target returned or NULL is returned if
         *  targetservice is not yet initialized or user passed an invalid node
         *  target to get the master proc handle
         */
        void masterProcChipTargetHandle(
            Target*& o_masterProcChipTargetHandle,
            const Target* i_pNodeTarget = NULL) const;

        /**
         *  @brief Returns the master processor chip target handle
         *
         *  Returns the master processor chip target handle for the given (or
         *  defaulted) node.  On nodes without an alternate master,
         *  it returns a handle to the only master, if found (NULL otherwise).
         *  On nodes with multiple potential
         *  masters, it returns a target handle to the acting master (NULL
         *  otherwise).  If targeting information is not yet accessible (very
         *  early in the host boot IPL), the returned target handle will be a
         *  sentinel value representing the master (whichever it may be)
         *
         *  @param[out] o_masterProcChipTarget
         *      Target handle of acting master processor chip for the given
         *      node (the one connected to PNOR)
         *  @param[in] i_pNodeTarget
         *      Target handle of node to search.  If NULL, HB will search
         *      whatver node it's running on, andFSP will search the physical
         *      drawer containing the lowest orderd fabric node ID
         *
         *  @pre Target Service must be initialized
         *
         *  @post Master processor chip target returned or a dummy value
         *      representing the acting master processor chip if the targeting
         *      information is not yet initialized
         *
         *  @return Error log handle indicating the status of the request
         *
         *  @retval NULL  Success, Master Proc handle is returned to the user
         *  @retval !NULL Failure, Failed to find the Master Proc Handle & NULL
         *      is returned to user
         */
        errlHndl_t queryMasterProcChipTargetHandle(
                  Target*& o_masterProcChipTargetHandle,
            const Target*  i_pNodeTarget = NULL) const;

        /**
         *  @brief Returns whether the specified entity path attribute exists
         *      for a specified target, and if so, the value of that attribute
         *
         *  Returns whether the specified entity path attribute exists for a
         *  specified target, and if so, the value of that attribute.  If the
         *  target doesn't exist, or the attribute doesn't correspond to an
         *  entity path attribute, or the entity path attribute doesn't exist
         *  for the target, then the routine returns false and the entity path
         *  value is invalid.
         *
         *  @param[in] i_attr Entity path attribute to read
         *  @param[in] i_pTarget Target handle to read the attribute from
         *  @param[out] o_entityPath Value of the target's associated entity
         *      path value
         *
         *  @pre N/A
         *
         *  @post See "return"
         *
         *  @return bool indicating whether the specified attribute exists
         *      for the specified target and whether the returned entity path
         *      value is valid
         *
         *  @retval true Specified attribute exists, entity path is valid
         *  @retval false Specified attribute does not exist, entity path is
         *      invalid
         */
        bool tryGetPath(
                  ATTRIBUTE_ID i_attr,
            const Target*      i_pTarget,
                  EntityPath&  o_entityPath) const;

        /**
         *  @brief Returns handles to targets associated to the specified
         *      target in a specific way, in depth first order
         *
         *  Returns handles to targets associated to the specified target,
         *  as indicated by an association type.  Based on the specified
         *  recursion level, the routine will determine the immediate
         *  associations, or all possible associations.  For example, if caller
         *  supplies a processor chip target and asks for its children targets,
         *  the routine will return the next set of targets in the physical
         *  hierarchy.  Conversely if the caller asks for ALL children targets
         *  for said source target, the routine will return all targets
         *  contained within the processor chip.  All targets will be returned
         *  in depth first order.
         *
         *  @param[out] o_list List of target handles that match the specified
         *      criteria.  Caller's list will be cleared initially.
         *  @param[in] i_pTarget Target from which to search for other targets.
         *      Must not be NULL.
         *  @param[in] i_type Type of association linking the specified target
         *      to candidate result targets
         *  @param[in] i_recursionLevel Whether to return candidate targets
         *      immediately associated to the specified target or recursively
         *      associated to it.
         *  @param[in] i_pPredicate Pointer to a predicate to be evaluated
         *      against each candidate target (as determined by the source
         *      target, type, and recursion level parameters).  If the predicate
         *      returns true, the target will be added to the result list.  A
         *      value of NULL acts as a predicate that always returns true.
         *
         *  @pre N/A
         *
         *  @post Caller's list cleared; list of target handles matching the
         *      specified criteria returned
         */
         void getAssociated(
                  TargetHandleList& o_list,
            const Target* const     i_pTarget,
            const ASSOCIATION_TYPE  i_type = CHILD,
            const RECURSION_LEVEL   i_recursionLevel = IMMEDIATE,
            const PredicateBase*    i_pPredicate = NULL) const;

        /**
         *  @brief Dump the target service for debug only
         *
         *  @post Output written to buffer
         */
        void dump() const;

#ifndef __HOSTBOOT_RUNTIME
        /**
         *  @brief Updates the targeting/attribute section data with the
         *  specified vector parameters.
         *
         *  This is the top level interface, would basically call the lower
         *  level attribute resource provider interface. The lower level
         *  interface would fetch each vector element and update each section
         *  with corresponding data from the offset specified.
         *
         *  @param[in] i_pages, vector of sectionRefData struct
         *
         *  @pre N/A
         *
         *  @post See "return"
         *
         *  @return bool indicates whether the write to section data is
         *  successful or not.
         *
         *  @retval true Section Data update successful
         *  @retval false Section Data update failed.
         */
        bool writeSectionData(const std::vector<sectionRefData>& i_pages);

        /**
         *  @brief Fill up the vector with  the targeting/attribute section
         *  data specified in the sectionId parameter.
         *
         *  This is the top level interface, would basically call the lower
         *  level attribute resource provider interface. The lower level
         *  interface would fetch section data as per the sectionId specified
         *  and push to vector reference.
         *
         *  @param[out] o_pages, vector of sectionRefData struct
         *  @param[in] i_sectionId, section type
         *  @param[in] i_nodeId, node Id
         *
         *  @pre N/A
         *
         *  @post See "return"
         *
         *  @return void would fill up the vectore references with complete
         *  section data in pages.
         *
         */

        void readSectionData(std::vector<sectionRefData>& o_pages,
                const SECTION_TYPE i_sectionId,
                const NODE_ID i_nodeId = NODE0);
#endif

        /**
         *  @brief Get the Next initialized node in the Target Service
         *   This is to support the iterator
         *
         *  It takes the present node id as input and computes the next
         *  incremental caller-visible node available in the system and
         *  return it to the user
         *
         *  @param[in] i_nodeId, present node Id
         *
         *  @return returns uint8_t as next node
         *
         *  @retval success case, Node Id, returns the next incremental
         *  initialized caller-visible node available
         *  @retval, Failure case, invalid node, if the present node is the
         *  last initialized caller-visible node available in incremental
         *  order or user passed an invalid nodeId
         */
        NODE_ID getNextInitializedNode(const NODE_ID i_node) const;

        /**
         *  @brief Get the Next caller-visible Target Handle in incremental
         *  order. This is to support the iterator.
         *
         *  It is take a target handle as input and compute the next incremental
         *  available caller-visible target handle in the system and return it
         *  to the user.
         *
         *  @param[in] i_pTarget, non-NULL Target Handle
         *
         *  @return Target Handle
         *
         *  @retval Target*, returns the next incremental caller-visible
         *   Target Handle
         *  @retval NULL, if the target handle passed is the last visible
         *  target handle available in incremental order in the target service.
         */
        Target* getNextTarget(const Target* i_pTarget) const;

        /**
         *  @brief Sets the isMasterNode Attribute to the Node Target handle
         *  Passed and takes care of syncing master node's system target handle
         *  with non-master system target handles.
         *
         *  @par Detailed Description
         *  It takes the node target handle as input which is required to set as
         *  master node and sets the isMasterNode Attribute associated to true
         *  and also unset the isMasterNode associated with all current master
         *  node target handle. Along with this it also takes care of syncing
         *  master node's system target attributes with non-master node system
         *  target's attribute in the system.
         *
         *  @param[in] i_pTarget, Non-Null Node Target handle
         *
         *  @return error handle is return
         *  @retval Success case, NULL is returned means the master node set and
         *  sync is successful
         *  @return, Failure case, !NULL error handle is returned means the
         *  master node couldn't be set as desired.
         */
        errlHndl_t setMasterNode(const Target* i_pTarget);

        /**
         *  @brief this gives the information whether a system target is
         *  master-node's system target or non-master-node's system target
         *
         *  It is takes system target handle as input and checks whether the
         *  system target is from master-node target tree or non-master node
         *  target tree.
         *
         *  @param[in] i_pTarget, Non-Null System Target handle
         *
         *  @return true, means the system target passed is a non-master node's
         *  system target.
         *  @return false, means the system target passed is a master node's
         *  system target.
         */
        bool isNonMasterNodeSystemTarget(const Target* i_pTarget) const;

        /*
         *  @brief give the total number of nodes in the targeting service
         *  for which node level binaries have been initialized .
         *
         *  @return total number of nodes in the targeting model initiailized.
         */
        uint8_t getNumInitializedNodes() const;

        /**
         *  @brief set the default Master Node and release the intialize flag
         *  for targetservice
         *
         *  @par Detailed Description:
         *  Searches for previous instance of master node, else sets the default
         *  node (i.e. first initialized node) as master node. And then releases
         *  the initialized flag of targetservice, Intializing targetservice
         *  fully
         *
         *  @pre targetservice().init() should have been called before this.
         *
         *  @post Target service is fully initialized along with a default
         *  master node.
         */

        void initDefaultMasterNode();

        /**
         *  @brief Returns the Node Target handle of the Master node in the
         *  system.
         *
         *  @par Detailed Description:
         *  Returns the Node Target handle of the Master node in the system.
         *  Caller must check for NULL Target handle
         *
         *  @param[out] o_masterNodeTarget node target handle of the master node
         *  in the system
         *
         *  @pre TargetService must be initialized.
         *
         *  @post Returns the node target handle of the master node. User
         *  will always get a valid target else targetservice will assert.
         *
         *  @return void
         */
        void getMasterNodeTarget(Target*& o_masterNodeTarget) const;

        /**
         *  @brief Returns Array of Targets from Targeting Image.
         *
         *  @par Detailed Description:
         *  Returns a pointer to the Array of Targets found in the Targeting
         *  Image as provided by the Attribute Data.
         *
         *  @param[in] i_attrData pointer to attribute data
         *
         *  @param[in] i_nodeId, node ID for the targeting image
         *
         *  @param[in] i_attrRP pointer to attribute resource provider
         *
         *  @param[out] o_maxTargets maximum targets in image
         *
         *  @pre TargetService must be initialized.
         *
         *  @post Returns pointer to Array of Targets from Targeting Image.
         *
         *  @return Target*
         */
        Target* getTargetArray(void *i_attrData,
                               NODE_ID i_nodeId,
                               AttrRP *i_attrRP,
                               uint32_t &o_maxTargets);

        /**
         *  @brief Returns Target Attribute information.
         *
         *  @par Detailed Description:
         *  Returns the Target Attribute information for the specified
         *  target and resource provider.
         *
         *  @param[in] i_target pointer to target
         *
         *  @param[in] i_attrRP pointer to attribute resource provider
         *
         *  @param[out] o_pAttrId pointer to array of attribute IDs
         *
         *  @param[out] o_ppAttrAddr pointer to array of attribute addresses
         *
         *  @pre TargetService must be initialized.
         *
         *  @post Returns the Target Attribute information for the specified
         *  target and resource provider.
         *
         *  @return Number of attributes in the arrays
         */
        uint32_t getTargetAttributes(Target*i_target,
                                     AttrRP *i_attrRP,
                                     ATTRIBUTE_ID* &o_pAttrId,
                                     AbstractPointer<void>* &o_ppAttrAddr);
#ifdef __HOSTBOOT_MODULE
        /**
         *  @brief Reset all hostboot mutex attributes
         *
         *  @par Detailed Description:
         *  Iterates through all targets and check each of their attributes to
         *  see if they are of type hbmutex. If we find a mutex attribute we will
         *  run mutex_init on it to reset it.
         *
         *  @pre TargetService must be initialized.
         *       AttrRp must be initialized
         *
         *  @post All hb mutex attributes on all targets have been reset
         *
         *  @return void
         */
        void resetMutexAttributes();
#endif
    private:

        /**
         *  @brief Structure, Node information specific
         */
        struct NodeSpecificInfo
        {

            NodeSpecificInfo() :
                nodeId(INVALID_NODE),
                initialized(false),
                isMasterNode(false),
                targets(NULL),
                maxTargets(0),
                pPnor(NULL)
            {
            }

            NODE_ID     nodeId;       ///< Node Id for the binary file
            bool        initialized;  ///< Is service initialized or not
            bool        isMasterNode; ///< Is this the master node
            Target      (*targets)[]; ///< Pointer to array of target objects
            uint32_t    maxTargets;   ///< Maximum # target objects in the array
            const void* pPnor;        ///< Pointer to the PNOR targeting section
        };

        /**
         *  @brief Node Specific information container
         */
        typedef std::vector< NodeSpecificInfo > NodeData_t;

        /**
         *  @brief Returns the first Target from the first initialized node
         *  from the pool of targets.
         *
         *  @param[out] o_firstTargetPtr First Target handle
         *
         *  @pre Target service must be initialized
         *
         *  @post Target Service returns the first Target from the first
         *  initialized node.
         *
         *  @returns void
         */
        void _getFirstTargetForIterators (Target*& o_firstTargetPtr) const;

#ifdef __HOSTBOOT_RUNTIME
        /**
         *  @brief Returns the first Target from the node's pool of targets if
         *  node is initialized.
         *
         *  @param[out] o_firstTargetPtr First Target handle or nullptr
         *
         *  @param[in] i_nodeId, node Id
         *
         *  @pre Target service must be initialized
         *
         *  @post Target Service returns the first Target from the node if node
         *  is initialized.
         *
         *  @returns void
         */
        void _getFirstTargetForIterators (Target*& o_firstTargetPtr,
                                          NODE_ID i_nodeId) const;
#endif

        /**
         *  @brief Configures the pool of targets
         *
         *  This function computes the maximum number of targets possible based
         *  on the PNOR (or override) image, and updates the target service to
         *  point to the start of the target array, wherever it may reside
         *
         *  @param[in] i_nodeContainer, struct to contain all node
         *  specific information of the type NodeSpecificInfo. May refer to
         *  structure definition
         *
         *  @param[in] i_attrRP, attribute resource provider to use if address
         *  translation is required. Defaults to NULL, ie, AttrRP Singleton.
         *
         *  @pre Target service must not be initialized
         *
         *  @post Target service target pool configured for access
         */
        void _configureTargetPool(NodeSpecificInfo& i_nodeContainer,
                                  AttrRP *i_attrRP = NULL);

        /**
         *  @brief Computes the maximum number of targets, caches the value
         *      and returns it to the caller
         *
         *  Computes the maximum number of targets possible based on the PNOR
         *  (or override) image and returns it to the caller
         *
         *  @param[in/out] io_nodeContainer, struct to contain all node
         *  specific information of the type NodeSpecificInfo. May refer to
         *  structure definition
         *
         *  @param[in] i_attrRP, attribute resource provider to use if address
         *  translation is required. Defaults to NULL, ie, AttrRP Singleton.
         *
         *  @pre Target service must not already be initialized
         *
         *  @post Target service updated with maximum target count in
         *  nodeContainer.
         *
         */
        void _maxTargets(NodeSpecificInfo & io_nodeContainer,
                         AttrRP *i_attrRP = NULL);


        //@NEBA
        /**
         *  @brief Returns handles targets associated to the specified target in
         *      a specific way as indicated by the input parameters.  Returns
         *      results in depth first order.
         *
         *  Returns handles to targets associated to the specified target,
         *  as indicated by an association type.  Based on the specified
         *  recursion level, the routine will determine the immediate
         *  associations, or all possible associations.  For example, if caller
         *  supplies a processor chip target and asks for its children targets,
         *  the routine will return the next set of targets in the physical
         *  hierarchy.  Conversely if the caller asks for ALL children targets
         *  for said source target, the routine will return all targets
         *  contained within the processor chip.  All searching is performed as
         *  a depth first search.  This routine will not clear the caller's
         *  input list when returning results.
         *
         *  @param[out] o_list List of target handles that match the specified
         *      criteria, not cleared by this function.
         *  @param[in] i_pSourceTarget Target from which to search for other
         *      targets.  Must not be NULL.  Function presumes caller has
         *      already screened out NULL targets.
         *  @param[in] i_type Type of association linking the specified target
         *      to candidate result targets
         *  @param[in] i_recursionLevel Whether to return candidate targets
         *      immediately associated to the specified target or recursively
         *      associated to it.
         *  @param[in] i_pPredicate Pointer to a predicate to be evaluated
         *      against each candidate target (as determined by the source
         *      target, type, and recursion level parameters).  If the predicate
         *      returns true, the target will be added to the result list.  A
         *      value of NULL acts as a predicate that always returns true.
         *
         *  @pre Input target must not be NULL
         *
         *  @post List of target handles matching the specified criteria
         *      added to end of caller's list
         */
        void _getAssociationsViaDfs(
                  TargetHandleList&    o_list,
            const Target* const        i_pSourceTarget,
            const ASSOCIATION_TYPE     i_type,
            const RECURSION_LEVEL      i_recursionLevel,
            const PredicateBase* const i_pPredicate) const;

        /**
         *  @brief Computes and stores the Top Level Target into iv_pSys
         *
         *  this should only be called to the exclusion of threads that might
         *   try to read or write iv_pSys.
         *
         *  @param NONE
         *
         *  @pre Target service must already be 'initialized'
         *
         *  @post Target service iv_pSys initialized with top TYPE_SYS
         *  target.
         *
         */
        void _setTopLevelTarget();

        // Instance variables
        bool        iv_initialized; ///< Is service initialized or not
        Target      * iv_pSys;      // Top Level Target

        NodeData_t iv_nodeData;

        // Disable copy constructor / assignment operator

        TargetService(
            const TargetService& i_right);

        TargetService& operator=(
            const TargetService& i_right);
};

/**
 *  @brief Singleton to access the only TargetService; deemphasized
 *      intentionally
 */
class TargetService;

TARG_DECLARE_SINGLETON(TARGETING::TargetService,theTargetService);

} // End namespace TARGETING

#endif // __TARGETING_COMMON_TARGETSERVICE_H
OpenPOWER on IntegriCloud