diff options
author | Joachim Fenkes <fenkes@de.ibm.com> | 2018-12-05 16:47:55 +0100 |
---|---|---|
committer | Sachin Gupta <sgupta2m@in.ibm.com> | 2019-02-13 21:37:51 -0600 |
commit | b9b668e5916e3310eacb95496cc0792d819b25f0 (patch) | |
tree | 78ce2d1f1a4ed46f5c1ad4d5c0536e8acb34b4ea /src/hwpf | |
parent | 6eb2a4c0f0d838967f29d124ae466b8c1920bf37 (diff) | |
download | talos-sbe-b9b668e5916e3310eacb95496cc0792d819b25f0.tar.gz talos-sbe-b9b668e5916e3310eacb95496cc0792d819b25f0.zip |
FAPI2: Multicast API 1/2: Platform-breaking changes
The Target gains a new template parameter, M, that specifies
the multicast type. This is propagated through all affected
header files.
A new target type is introduced, TARGET_TYPE_MULTICAST, and
platform specific assertions put in place to prevent users
from creating such targets before the platform supports it.
Target also grows a new inline function for updating MC targets.
Platforms not supporting MC can provide a dummy implementation.
The example platform code in fapi2/include/plat/plat_target.H
is updated with minimal example code for platform implementers.
Change-Id: Ia0990f26890dc5c719caca608cd134a4964a3acf
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/69456
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: HWSV CI <hwsv-ci+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Matt K. Light <mklight@us.ibm.com>
Tested-by: PPE CI <ppe-ci+hostboot@us.ibm.com>
Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Reviewed-by: RAJA DAS <rajadas2@in.ibm.com>
Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/70866
Reviewed-by: Sachin Gupta <sgupta2m@in.ibm.com>
Diffstat (limited to 'src/hwpf')
-rw-r--r-- | src/hwpf/hw_access.H | 78 | ||||
-rw-r--r-- | src/hwpf/multicast.H | 54 | ||||
-rw-r--r-- | src/hwpf/plat_target.H | 10 | ||||
-rw-r--r-- | src/hwpf/target.H | 92 |
4 files changed, 89 insertions, 145 deletions
diff --git a/src/hwpf/hw_access.H b/src/hwpf/hw_access.H index ab17a763..d00304e4 100644 --- a/src/hwpf/hw_access.H +++ b/src/hwpf/hw_access.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER sbe Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2012,2017 */ +/* Contributors Listed Below - COPYRIGHT 2012,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -105,9 +105,9 @@ namespace fapi2 /// @param[in] i_address SCOM register address to read from. /// @param[out] o_data Buffer that holds data read from HW target. /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. - template< TargetType K, typename V > + template< TargetType K, MulticastType M, typename V > __attribute__((always_inline)) - inline ReturnCode getScom(const Target<K, V>& i_target, const uint64_t i_address, + inline ReturnCode getScom(const Target<K, M, V>& i_target, const uint64_t i_address, buffer<uint64_t>& o_data) { fapi2::ReturnCode l_rc; @@ -125,9 +125,9 @@ namespace fapi2 /// @param[in] i_address SCOM register address to write to. /// @param[in] i_data Buffer that holds data to write into address. /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. - template< TargetType K, typename V > + template< TargetType K, MulticastType M, typename V > __attribute__((always_inline)) - inline ReturnCode putScom(const Target<K, V>& i_target, const uint64_t i_address, + inline ReturnCode putScom(const Target<K, M, V>& i_target, const uint64_t i_address, const buffer<uint64_t> i_data) { fapi2::ReturnCode l_rc; @@ -146,8 +146,8 @@ namespace fapi2 /// @param[in] i_data Buffer that holds data to be modified. /// @param[in] i_modifyMode The modify mode (or/and/xor). /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. - template< TargetType K, typename V > - inline ReturnCode modifyScom(const Target<K, V>& i_target, + template< TargetType K, MulticastType M, typename V > + inline ReturnCode modifyScom(const Target<K, M, V>& i_target, const uint64_t i_address, const buffer<uint64_t> i_data, const ChipOpModifyMode i_modifyMode) @@ -196,8 +196,8 @@ __fapi2exit__: /// @param[in] i_data Buffer that holds data to write into address. /// @param[in] i_mask Buffer that holds the mask value. /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. - template< TargetType K, typename V > - inline ReturnCode putScomUnderMask( const Target<K, V>& i_target, + template< TargetType K, MulticastType M, typename V > + inline ReturnCode putScomUnderMask( const Target<K, M, V>& i_target, const uint64_t i_address, const buffer<uint64_t> i_data, const buffer<uint64_t> i_mask) @@ -214,8 +214,8 @@ __fapi2exit__: /// @param[in] i_address CFAM register address to read from. /// @param[out] o_data Buffer that holds data read from HW target. /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. - template< TargetType K, typename V > - inline ReturnCode getCfamRegister(const Target<K, V>& i_target, + template< TargetType K, MulticastType M, typename V > + inline ReturnCode getCfamRegister(const Target<K, M, V>& i_target, const uint32_t i_address, buffer<uint32_t>& o_data) { @@ -234,8 +234,8 @@ __fapi2exit__: /// @param[in] i_address CFAM register address to write to. /// @param[in] i_data Buffer that holds data to write into address. /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. - template< TargetType K, typename V > - inline ReturnCode putCfamRegister(const Target<K, V>& i_target, + template< TargetType K, MulticastType M, typename V > + inline ReturnCode putCfamRegister(const Target<K, M, V>& i_target, const uint32_t i_address, buffer<uint32_t>& i_data) { @@ -255,8 +255,8 @@ __fapi2exit__: /// @param[in] i_data Buffer that holds data to be modified. /// @param[in] i_modifyMode The modify mode (or/and/xor). /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. - template< TargetType K, typename V > - inline ReturnCode modifyCfamRegister(const Target<K, V>& i_target, + template< TargetType K, MulticastType M, typename V > + inline ReturnCode modifyCfamRegister(const Target<K, M, V>& i_target, const uint32_t i_address, const buffer<uint32_t>& i_data, const ChipOpModifyMode i_modifyMode) @@ -277,8 +277,8 @@ __fapi2exit__: /// @param[in] i_ringID Ring ID that will identify the Ring in the image. /// @param[in] i_ringMode Ring operation mode. /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. - template< TargetType K, typename V > - inline ReturnCode putRing(const Target<K, V>& i_target, + template< TargetType K, MulticastType M, typename V > + inline ReturnCode putRing(const Target<K, M, V>& i_target, const RingId_t i_ringID, const RingMode i_ringMode = RING_MODE_HEADER_CHECK) { @@ -299,8 +299,8 @@ __fapi2exit__: /// @param[out] o_data Buffer that holds data read from HW target. /// @param[in] i_ringMode Ring operation mode. /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. - template< TargetType K, typename V > - inline ReturnCode getRing(const Target<K, V>& i_target, + template< TargetType K, MulticastType M, typename V > + inline ReturnCode getRing(const Target<K, M, V>& i_target, const scanRingId_t i_address, variable_buffer& o_data, const RingMode i_ringMode = 0) @@ -329,8 +329,8 @@ __fapi2exit__: /// @param[in] i_modifyMode The modify mode (or/and/xor) /// @param[in] i_ringMode Ring operation mode. /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. - template< TargetType K, typename V > - inline ReturnCode modifyRing(const Target<K, V>& i_target, + template< TargetType K, MulticastType M, typename V > + inline ReturnCode modifyRing(const Target<K, M, V>& i_target, const scanRingId_t i_address, variable_buffer& i_data, const ChipOpModifyMode i_modifyMode, @@ -382,8 +382,8 @@ __fapi2exit__: /// SCOM_BULK_WRITE_MODE operations are not supported due to /// hardware limitations. /// - template< TargetType K, typename V > - fapi2::ReturnCode multiScom (const Target<K, V>& i_target, + template< TargetType K, MulticastType M, typename V > + fapi2::ReturnCode multiScom (const Target<K, M, V>& i_target, MultiScom& io_multiScomObj) { } @@ -436,8 +436,8 @@ __fapi2exit__: /// the quotes for the cronus environment /// #ifdef FAPI_SUPPORT_SPY_AS_ENUM - template< TargetType K, typename V > - inline ReturnCode getSpy(const Target<K, V>& i_target, + template< TargetType K, MulticastType M, typename V > + inline ReturnCode getSpy(const Target<K, M, V>& i_target, const spyId_t i_spyId, variable_buffer& o_data) { @@ -446,8 +446,8 @@ __fapi2exit__: } #endif #ifdef FAPI_SUPPORT_SPY_AS_STRING - template< TargetType K, typename V > - inline ReturnCode getSpy(const Target<K, V>& i_target, + template< TargetType K, MulticastType M, typename V > + inline ReturnCode getSpy(const Target<K, M, V>& i_target, const char * const i_spyId, variable_buffer& o_data) { @@ -495,8 +495,8 @@ __fapi2exit__: /// the quotes for the cronus environment /// #ifdef FAPI_SUPPORT_SPY_AS_ENUM - template< TargetType K, typename V > - inline ReturnCode putSpy(const Target<K, V>& i_target, + template< TargetType K, MulticastType M, typename V > + inline ReturnCode putSpy(const Target<K, M, V>& i_target, const spyId_t i_spyId, variable_buffer& i_data) { @@ -505,8 +505,8 @@ __fapi2exit__: } #endif #ifdef FAPI_SUPPORT_SPY_AS_STRING - template< TargetType K, typename V > - inline ReturnCode putSpy(const Target<K, V>& i_target, + template< TargetType K, MulticastType M, typename V > + inline ReturnCode putSpy(const Target<K, M, V>& i_target, const char* const i_spyId, variable_buffer& i_data) { @@ -535,8 +535,8 @@ __fapi2exit__: /// See fapiPutSpy for details on spy id specifics. /// #ifdef FAPI_SUPPORT_SPY_AS_ENUM - template< TargetType K, typename V > - inline ReturnCode putSpyImage(const Target<K, V>& i_target, + template< TargetType K, MulticastType M, typename V > + inline ReturnCode putSpyImage(const Target<K, M, V>& i_target, const spyId_t i_spyId, const variable_buffer& i_data, variable_buffer& o_imageData) @@ -546,8 +546,8 @@ __fapi2exit__: } #endif #ifdef FAPI_SUPPORT_SPY_AS_STRING - template< TargetType K, typename V > - inline ReturnCode putSpyImage(const Target<K, V>& i_target, + template< TargetType K, MulticastType M, typename V > + inline ReturnCode putSpyImage(const Target<K, M, V>& i_target, const char* const i_spyId, const variable_buffer& i_data, variable_buffer& o_imageData) @@ -574,8 +574,8 @@ __fapi2exit__: /// See fapiPutSpy for details on spy id specifics. /// #ifdef FAPI_SUPPORT_SPY_AS_ENUM - template< TargetType K, typename V > - inline ReturnCode getSpyImage(const Target<K, V>& i_target, + template< TargetType K, MulticastType M, typename V > + inline ReturnCode getSpyImage(const Target<K, M, V>& i_target, const spyId_t i_spyId, variable_buffer& o_data, const variable_buffer& i_imageData) @@ -585,8 +585,8 @@ __fapi2exit__: } #endif #ifdef FAPI_SUPPORT_SPY_AS_STRING - template< TargetType K, typename V > - inline ReturnCode getSpyImage(const Target<K, V>& i_target, + template< TargetType K, MulticastType M, typename V > + inline ReturnCode getSpyImage(const Target<K, M, V>& i_target, const char * const i_spyId, variable_buffer& o_data, const variable_buffer& i_imageData) diff --git a/src/hwpf/multicast.H b/src/hwpf/multicast.H deleted file mode 100644 index 8ec0c4a7..00000000 --- a/src/hwpf/multicast.H +++ /dev/null @@ -1,54 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/hwpf/multicast.H $ */ -/* */ -/* OpenPOWER sbe Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2016,2017 */ -/* */ -/* */ -/* 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 __FAPI2_MULTICAST__ -#define __FAPI2_MULTICAST__ - -#include <fapi2_multicast.H> - -namespace fapi2 -{ - -template<MulticastType M, MulticastGroup G, typename V> -template<MulticastType O, MulticastGroup N> -inline void Multicast<M, G, V>::updateHandle(V& i_value) -{ - // Update handle only if multicast bit is set in handle, else we leave the - // handle unchanged. This enables the same procedure to work with both - // multicast and unicast targets - if(i_value.fields.is_multicast) - { - // Update the handle to reflect the new multicast type and group - i_value.fields.chiplet_num = (0x40) | (O << 3) | N; - } -} - -template<MulticastType M, MulticastGroup G, typename V> -inline bool Multicast<M, G, V>::isMulticast() const -{ - return iv_handle.fields.is_multicast; -} - -} - -#endif diff --git a/src/hwpf/plat_target.H b/src/hwpf/plat_target.H index 1d32dbb8..8606ffa1 100644 --- a/src/hwpf/plat_target.H +++ b/src/hwpf/plat_target.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER sbe Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2015,2017 */ +/* Contributors Listed Below - COPYRIGHT 2015,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -33,6 +33,7 @@ #include <stdint.h> #include <target_types.H> #include <target_states.H> +#include <multicast_defs.H> #include <assert.h> #include <plat_target_parms.H> #include <vector> @@ -53,6 +54,13 @@ static const uint8_t PCI0_CHIPLET = 0x0D; // namespace fapi2 { + template<TargetType K, MulticastType M, typename V> + static constexpr void plat_apply_target_limits(void) + { + static_assert(!(K & TARGET_TYPE_MULTICAST), + "Multicast targets are not supported on this platform"); + } + typedef enum plat_target_type { PPE_TARGET_TYPE_NONE = 0x00, diff --git a/src/hwpf/target.H b/src/hwpf/target.H index 09f5793d..5b746f0e 100644 --- a/src/hwpf/target.H +++ b/src/hwpf/target.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER sbe Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2012,2017 */ +/* Contributors Listed Below - COPYRIGHT 2012,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -33,7 +33,6 @@ #include <plat_target.H> #include <plat_target_parms.H> #include <fapi2_target.H> -#include <multicast.H> #include <plat_trace.H> #include <utils.H> #include <stdint.h> @@ -149,8 +148,8 @@ namespace fapi2 /// @param[in] i_right Reference to Target to assign from. /// @return Reference to 'this' Target /// - template<TargetType K, typename V> - Target<K, V>& Target<K, V>::operator=(const Target& i_right) + template<TargetType K, MulticastType M, typename V> + Target<K, M, V>& Target<K, M, V>::operator=(const Target& i_right) { this->iv_handle.value = i_right.iv_handle.value; return *this; @@ -162,8 +161,8 @@ namespace fapi2 /// @note Platforms need to define this so that the physical /// targets are determined to be equivilent rather than just the handles /// - template<TargetType K, typename V> - bool Target<K, V>::operator==(const Target& i_right) const + template<TargetType K, MulticastType M, typename V> + bool Target<K, M, V>::operator==(const Target& i_right) const { if (this->iv_handle.value == i_right.iv_handle.value) return true; @@ -178,8 +177,8 @@ namespace fapi2 /// @note Platforms need to define this so that the physical /// targets are determined to be equivilent rather than just the handles /// - template<TargetType K, typename V> - bool Target<K, V>::operator!=(const Target& i_right) const + template<TargetType K, MulticastType M, typename V> + bool Target<K, M, V>::operator!=(const Target& i_right) const { if (this->iv_handle.value != i_right.iv_handle.value) return true; @@ -190,11 +189,11 @@ namespace fapi2 /// /// @brief Get this target's immediate parent /// @tparam T The type of the parent - /// @return Target<T, V> a target representing the parent + /// @return Target<T, M, V> a target representing the parent /// - template<TargetType K, typename V> + template<TargetType K, MulticastType M, typename V> template<TargetType T> - inline Target<T, V> Target<K, V>::getParent(void) const + inline Target<T, M, V> Target<K, M, V>::getParent(void) const { constexpr TargetType TARGET_TYPE_PROC_CHILDREN = TARGET_TYPE_EQ | TARGET_TYPE_PERV | TARGET_TYPE_EX | @@ -273,23 +272,11 @@ namespace fapi2 { return static_cast<V>(G_vec_targets[(static_cast<plat_target_handle_t>(get()).getTargetInstance() / CORES_PER_EX) + EX_TARGET_OFFSET]); } - } - - /// - /// @brief Get this target's immediate parent - specialization for compound - // target (PROC_CHIP | CORE | EX) - /// @tparam T The type of the parent - /// @return Target<T, plat_target_handle_t> a target representing the parent - /// - template<> - template<TargetType T> - Target<T, plat_target_handle_t> - Target<TARGET_TYPE_PROC_CHIP | TARGET_TYPE_CORE | TARGET_TYPE_EX | TARGET_TYPE_PERV, - plat_target_handle_t>::getParent(void) const - { - static_assert(((T == TARGET_TYPE_PROC_CHIP) || (T == TARGET_TYPE_EQ)), - "Wrong parent target type"); - return static_cast<plat_target_handle_t>(get()).getParent(T); + constexpr TargetType TARGET_TYPE_CORE_OR_EX = TARGET_TYPE_CORE | TARGET_TYPE_EX; + if((TARGET_TYPE_EQ == T) && ((K & (TARGET_TYPE_CORE_OR_EX)) != TARGET_TYPE_NONE)) + { + return get().getParent(T); + } } /// @brief Get this target's children - handles EQ/EX/EC conversions @@ -297,19 +284,19 @@ namespace fapi2 /// @tparam V The plat target handle type /// @tparam T The type of child /// @param[in] i_state The desired TargetState of the children - /// @return std::vector<Target<T, V> > a vector of present/functional + /// @return std::vector<Target<T, M, V> > a vector of present/functional /// children /// @warning The children are returned in order, ex child[0] is /// std::vector[0] - template<TargetType K, typename V> + template<TargetType K, MulticastType M, typename V> template<TargetType T> - std::vector<Target<T, V>> - Target<K, V>::getChildren(const TargetState i_state) const + std::vector<Target<T, M, V>> + Target<K, M, V>::getChildren(const TargetState i_state) const { constexpr TargetType L = static_cast<TargetType>(K & ~(TARGET_TYPE_PROC_CHIP)); constexpr plat_target_type_t P = fapiTargetTypeToPlatTargetType<T>(); - static_assert(sizeof(Target<T, V>) == sizeof(plat_target_handle_t), + static_assert(sizeof(Target<T, M, V>) == sizeof(plat_target_handle_t), "Sizes of plat target and FAPI target must match"); static_assert(((L == TARGET_TYPE_EQ) || (L == TARGET_TYPE_EX) || (K == TARGET_TYPE_PROC_CHIP)), @@ -329,19 +316,19 @@ namespace fapi2 "improper child of fapi2::TARGET_TYPE_EX"); - std::vector<Target<T, V> > l_children; + std::vector<Target<T, M, V> > l_children; static_cast<plat_target_handle_t>(get()).getChildren(K, T, P, i_state, reinterpret_cast<std::vector<plat_target_handle>&>(l_children)); return l_children; } // Specialization of getChildren, filtered for the chip target - template<TargetType K, typename V> + template<TargetType K, MulticastType M, typename V> template<TargetType T> - std::vector<Target<T, V> > - Target<K, V>::getChildren(const TargetFilter i_filter, + std::vector<Target<T, M, V> > + Target<K, M, V>::getChildren(const TargetFilter i_filter, const TargetState i_state) const { - static_assert(sizeof(Target<T, V>) == sizeof(plat_target_handle_t), + static_assert(sizeof(Target<T, M, V>) == sizeof(plat_target_handle_t), "Sizes of plat target and FAPI target must match"); static_assert((K == TARGET_TYPE_PROC_CHIP), "Parent target must be the proc chip"); @@ -361,9 +348,9 @@ namespace fapi2 /// @brief Is the target functional? /// @return true if target is functional, false if non-functional /// - template<TargetType K, typename V> + template<TargetType K, MulticastType M, typename V> inline bool - Target<K, V>::isFunctional(void) const + Target<K, M, V>::isFunctional(void) const { return static_cast<plat_target_handle_t>(get()).getFunctional(); } @@ -372,9 +359,9 @@ namespace fapi2 /// @brief Returns the chiplet number for this Target /// @return The chiplet number /// - template<TargetType K, typename V> + template<TargetType K, MulticastType M, typename V> inline uint8_t - Target<K, V>::getChipletNumber(void) const + Target<K, M, V>::getChipletNumber(void) const { return static_cast<plat_target_handle_t>(iv_handle).fields.chiplet_num; } @@ -389,8 +376,8 @@ namespace fapi2 /// @post The contents of the buffer is replaced with the string /// representation of the target /// - template< TargetType T, typename V > - inline void toString(const Target<T, V>& i_target, char* i_buffer, size_t i_bsize) + template< TargetType T, MulticastType M, typename V > + inline void toString(const Target<T, M, V>& i_target, char* i_buffer, size_t i_bsize) { snprintf(i_buffer, i_bsize, "Target 0x%lx/0x%x", i_target.get(), T); } @@ -399,15 +386,15 @@ namespace fapi2 /// @brief Return the string interpretation of this target /// @tparam T The type of the target /// @tparam B The type of the buffer - /// @param[in] A pointer to the Target<T, V> + /// @param[in] A pointer to the Target<T, M, V> /// @param[in] i_buffer buffer to write in to /// @param[in] i_bsize size of the buffer /// @return void /// @post The contents of the buffer is replaced with the string /// representation of the target /// - template< TargetType T, typename V > - inline void toString(const Target<T, V>* i_target, char* i_buffer, size_t i_bsize) + template< TargetType T, MulticastType M, typename V > + inline void toString(const Target<T, M, V>* i_target, char* i_buffer, size_t i_bsize) { snprintf(i_buffer, i_bsize, "Target 0x%lx/0x%x", i_target->get(), T); } @@ -417,14 +404,17 @@ namespace fapi2 /// @tparam T The type of the target /// @param[in] Ordinal representing the ordinal number of /// the desired target - /// @return Target<T, V> the target requested + /// @return Target<T, M, V> the target requested /// - template<TargetType T, typename V> - inline Target<T, V> getTarget(uint64_t Ordinal) + template<TargetType T, MulticastType M, typename V> + inline Target<T, M, V> getTarget(uint64_t Ordinal) { // For testing - return Target<T, V>(Ordinal); + return Target<T, M, V>(Ordinal); } + + template<TargetType T, MulticastType M, typename V> + inline void Target<T, M, V>::mcUpdateHandle() {}; } #endif |