gp.hh revision 13521
111308Santhony.gutierrez@amd.com/***************************************************************************** 211308Santhony.gutierrez@amd.com 311308Santhony.gutierrez@amd.com Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 411308Santhony.gutierrez@amd.com more contributor license agreements. See the NOTICE file distributed 511308Santhony.gutierrez@amd.com with this work for additional information regarding copyright ownership. 611308Santhony.gutierrez@amd.com Accellera licenses this file to you under the Apache License, Version 2.0 711308Santhony.gutierrez@amd.com (the "License"); you may not use this file except in compliance with the 811308Santhony.gutierrez@amd.com License. You may obtain a copy of the License at 911308Santhony.gutierrez@amd.com 1011308Santhony.gutierrez@amd.com http://www.apache.org/licenses/LICENSE-2.0 1111308Santhony.gutierrez@amd.com 1211308Santhony.gutierrez@amd.com Unless required by applicable law or agreed to in writing, software 1311308Santhony.gutierrez@amd.com distributed under the License is distributed on an "AS IS" BASIS, 1411308Santhony.gutierrez@amd.com WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 1511308Santhony.gutierrez@amd.com implied. See the License for the specific language governing 1611308Santhony.gutierrez@amd.com permissions and limitations under the License. 1712697Santhony.gutierrez@amd.com 1812697Santhony.gutierrez@amd.com *****************************************************************************/ 1912697Santhony.gutierrez@amd.com 2011308Santhony.gutierrez@amd.com#ifndef __SYSTEMC_EXT_TLM_CORE_2_GENERIC_PAYLOAD_GP_HH__ 2111308Santhony.gutierrez@amd.com#define __SYSTEMC_EXT_TLM_CORE_2_GENERIC_PAYLOAD_GP_HH__ 2211308Santhony.gutierrez@amd.com 2311308Santhony.gutierrez@amd.com#include <systemc> 2411308Santhony.gutierrez@amd.com#include <typeinfo> // std::type_info 2511308Santhony.gutierrez@amd.com 2611308Santhony.gutierrez@amd.com#include "tlm_core/2/generic_payload/array.hh" 2711308Santhony.gutierrez@amd.com 2811308Santhony.gutierrez@amd.comnamespace tlm 2911308Santhony.gutierrez@amd.com{ 3011308Santhony.gutierrez@amd.com 3111308Santhony.gutierrez@amd.comclass tlm_generic_payload; 3211308Santhony.gutierrez@amd.com 3312697Santhony.gutierrez@amd.comclass tlm_mm_interface 3412697Santhony.gutierrez@amd.com{ 3511308Santhony.gutierrez@amd.com public: 3611308Santhony.gutierrez@amd.com virtual void free(tlm_generic_payload *) = 0; 3711308Santhony.gutierrez@amd.com virtual ~tlm_mm_interface() {} 3811308Santhony.gutierrez@amd.com}; 3911308Santhony.gutierrez@amd.com 4011308Santhony.gutierrez@amd.com//--------------------------------------------------------------------------- 4111308Santhony.gutierrez@amd.com// Classes and helpers for the extension mechanism 4211308Santhony.gutierrez@amd.com//--------------------------------------------------------------------------- 4311308Santhony.gutierrez@amd.com// Helper function: 4411308Santhony.gutierrez@amd.comunsigned int max_num_extensions(); 4511308Santhony.gutierrez@amd.com 4611308Santhony.gutierrez@amd.com// This class can be used for storing pointers to the extension classes, used 4711308Santhony.gutierrez@amd.com// in tlm_generic_payload: 4811308Santhony.gutierrez@amd.comclass tlm_extension_base 4911308Santhony.gutierrez@amd.com{ 5011308Santhony.gutierrez@amd.com public: 5111308Santhony.gutierrez@amd.com virtual tlm_extension_base *clone() const = 0; 5211308Santhony.gutierrez@amd.com virtual void free() { delete this; } 5311308Santhony.gutierrez@amd.com virtual void copy_from(tlm_extension_base const &) = 0; 5411308Santhony.gutierrez@amd.com protected: 5511308Santhony.gutierrez@amd.com virtual ~tlm_extension_base() {} 5611308Santhony.gutierrez@amd.com static unsigned int register_extension(const std::type_info &); 5711308Santhony.gutierrez@amd.com}; 5811308Santhony.gutierrez@amd.com 5911308Santhony.gutierrez@amd.com// Base class for all extension classes, derive your extension class in 6011308Santhony.gutierrez@amd.com// the following way: 6111308Santhony.gutierrez@amd.com// class my_extension : public tlm_extension<my_extension> { ... 6211308Santhony.gutierrez@amd.com// This triggers proper extension registration during C++ static 6311308Santhony.gutierrez@amd.com// contruction time. my_extension::ID will hold the unique index in the 6411308Santhony.gutierrez@amd.com// tlm_generic_payload::m_extensions array. 6511308Santhony.gutierrez@amd.comtemplate <typename T> 6611308Santhony.gutierrez@amd.comclass tlm_extension : public tlm_extension_base 6711308Santhony.gutierrez@amd.com{ 6811308Santhony.gutierrez@amd.com public: 6911308Santhony.gutierrez@amd.com virtual tlm_extension_base *clone() const = 0; 7011308Santhony.gutierrez@amd.com virtual void copy_from(tlm_extension_base const &ext) = 0; 7111308Santhony.gutierrez@amd.com virtual ~tlm_extension() {} 7211308Santhony.gutierrez@amd.com const static unsigned int ID; 7311308Santhony.gutierrez@amd.com}; 7411308Santhony.gutierrez@amd.com 7511308Santhony.gutierrez@amd.comtemplate <typename T> 7611308Santhony.gutierrez@amd.comconst unsigned int tlm_extension<T>::ID = 7711308Santhony.gutierrez@amd.com tlm_extension_base::register_extension(typeid(T)); 7811308Santhony.gutierrez@amd.com 7911308Santhony.gutierrez@amd.com//--------------------------------------------------------------------------- 8011308Santhony.gutierrez@amd.com// enumeration types 8111308Santhony.gutierrez@amd.com//--------------------------------------------------------------------------- 8211308Santhony.gutierrez@amd.comenum tlm_command 8311308Santhony.gutierrez@amd.com{ 8411308Santhony.gutierrez@amd.com TLM_READ_COMMAND, 8511308Santhony.gutierrez@amd.com TLM_WRITE_COMMAND, 8611308Santhony.gutierrez@amd.com TLM_IGNORE_COMMAND 8711308Santhony.gutierrez@amd.com}; 8811308Santhony.gutierrez@amd.com 8911308Santhony.gutierrez@amd.comenum tlm_response_status 9011308Santhony.gutierrez@amd.com{ 9111308Santhony.gutierrez@amd.com TLM_OK_RESPONSE = 1, 9211308Santhony.gutierrez@amd.com TLM_INCOMPLETE_RESPONSE = 0, 9311308Santhony.gutierrez@amd.com TLM_GENERIC_ERROR_RESPONSE = -1, 9411308Santhony.gutierrez@amd.com TLM_ADDRESS_ERROR_RESPONSE = -2, 9511308Santhony.gutierrez@amd.com TLM_COMMAND_ERROR_RESPONSE = -3, 9611308Santhony.gutierrez@amd.com TLM_BURST_ERROR_RESPONSE = -4, 9711308Santhony.gutierrez@amd.com TLM_BYTE_ENABLE_ERROR_RESPONSE = -5 9811308Santhony.gutierrez@amd.com}; 9911308Santhony.gutierrez@amd.com 10011308Santhony.gutierrez@amd.comenum tlm_gp_option 10111308Santhony.gutierrez@amd.com{ 10211308Santhony.gutierrez@amd.com TLM_MIN_PAYLOAD, 10311308Santhony.gutierrez@amd.com TLM_FULL_PAYLOAD, 10411308Santhony.gutierrez@amd.com TLM_FULL_PAYLOAD_ACCEPTED 10511308Santhony.gutierrez@amd.com}; 10611308Santhony.gutierrez@amd.com 10711308Santhony.gutierrez@amd.com#define TLM_BYTE_DISABLED 0x0 10811308Santhony.gutierrez@amd.com#define TLM_BYTE_ENABLED 0xff 10911308Santhony.gutierrez@amd.com 11011308Santhony.gutierrez@amd.com//--------------------------------------------------------------------------- 11111308Santhony.gutierrez@amd.com// The generic payload class: 11211308Santhony.gutierrez@amd.com//--------------------------------------------------------------------------- 11311308Santhony.gutierrez@amd.com 11411308Santhony.gutierrez@amd.comextern template class tlm_array<tlm_extension_base *>; 11511308Santhony.gutierrez@amd.com 11611308Santhony.gutierrez@amd.comclass tlm_generic_payload 11711308Santhony.gutierrez@amd.com{ 11811308Santhony.gutierrez@amd.com public: 11911308Santhony.gutierrez@amd.com tlm_generic_payload(); 12011308Santhony.gutierrez@amd.com explicit tlm_generic_payload(tlm_mm_interface *mm); 12111308Santhony.gutierrez@amd.com 12211308Santhony.gutierrez@amd.com void 12311308Santhony.gutierrez@amd.com acquire() 12411308Santhony.gutierrez@amd.com { 12511308Santhony.gutierrez@amd.com sc_assert(m_mm != 0); 12611308Santhony.gutierrez@amd.com m_ref_count++; 12711308Santhony.gutierrez@amd.com } 12811308Santhony.gutierrez@amd.com 12911308Santhony.gutierrez@amd.com void 13011308Santhony.gutierrez@amd.com release() 13111308Santhony.gutierrez@amd.com { 13211308Santhony.gutierrez@amd.com sc_assert(m_mm != 0 && m_ref_count > 0); 13311308Santhony.gutierrez@amd.com if (--m_ref_count == 0) 13411308Santhony.gutierrez@amd.com m_mm->free(this); 13511308Santhony.gutierrez@amd.com } 13611308Santhony.gutierrez@amd.com 13711308Santhony.gutierrez@amd.com int get_ref_count() const { return m_ref_count; } 13811308Santhony.gutierrez@amd.com 13911308Santhony.gutierrez@amd.com void set_mm(tlm_mm_interface *mm) { m_mm = mm; } 14011308Santhony.gutierrez@amd.com bool has_mm() const { return m_mm != 0; } 14111308Santhony.gutierrez@amd.com 14211308Santhony.gutierrez@amd.com void reset(); 14311308Santhony.gutierrez@amd.com 14411308Santhony.gutierrez@amd.com private: 14511692Santhony.gutierrez@amd.com // Disabled copy ctor and assignment operator. 14611308Santhony.gutierrez@amd.com tlm_generic_payload(const tlm_generic_payload &x); 14711308Santhony.gutierrez@amd.com tlm_generic_payload &operator = (const tlm_generic_payload &x); 14811308Santhony.gutierrez@amd.com 14911308Santhony.gutierrez@amd.com public: 15011308Santhony.gutierrez@amd.com // Non-virtual deep-copying of the object. 15111308Santhony.gutierrez@amd.com void deep_copy_from(const tlm_generic_payload &other); 15211308Santhony.gutierrez@amd.com 15311308Santhony.gutierrez@amd.com // To update the state of the original generic payload from a deep copy. 15411308Santhony.gutierrez@amd.com // Assumes that "other" was created from the original by calling 15511308Santhony.gutierrez@amd.com // deep_copy_from Argument use_byte_enable_on_read determines whether to 15611308Santhony.gutierrez@amd.com // use or ignores byte enables when copying back the data array on a read 15711308Santhony.gutierrez@amd.com // command. 15811308Santhony.gutierrez@amd.com 15911308Santhony.gutierrez@amd.com void update_original_from(const tlm_generic_payload &other, 16011308Santhony.gutierrez@amd.com bool use_byte_enable_on_read=true); 16111308Santhony.gutierrez@amd.com 16211308Santhony.gutierrez@amd.com void update_extensions_from(const tlm_generic_payload &other); 16311308Santhony.gutierrez@amd.com 16411308Santhony.gutierrez@amd.com // Free all extensions. Useful when reusing a cloned transaction that 16511308Santhony.gutierrez@amd.com // doesn't have memory manager. Normal and sticky extensions are freed and 16611308Santhony.gutierrez@amd.com // extension array cleared. 16711308Santhony.gutierrez@amd.com void free_all_extensions(); 16811308Santhony.gutierrez@amd.com 16911308Santhony.gutierrez@amd.com virtual ~tlm_generic_payload(); 17011308Santhony.gutierrez@amd.com 17111308Santhony.gutierrez@amd.com //---------------- 17211308Santhony.gutierrez@amd.com // API (including setters & getters). 17311308Santhony.gutierrez@amd.com //--------------- 17411308Santhony.gutierrez@amd.com 17511308Santhony.gutierrez@amd.com // Command related method. 17611308Santhony.gutierrez@amd.com bool is_read() const { return (m_command == TLM_READ_COMMAND); } 17711308Santhony.gutierrez@amd.com void set_read() { m_command = TLM_READ_COMMAND; } 17811308Santhony.gutierrez@amd.com bool is_write() const { return (m_command == TLM_WRITE_COMMAND); } 17911308Santhony.gutierrez@amd.com void set_write() { m_command = TLM_WRITE_COMMAND; } 18011308Santhony.gutierrez@amd.com tlm_command get_command() const { return m_command; } 18111308Santhony.gutierrez@amd.com void set_command(const tlm_command command) { m_command = command; } 18211308Santhony.gutierrez@amd.com 18311308Santhony.gutierrez@amd.com // Address related methods. 18411308Santhony.gutierrez@amd.com sc_dt::uint64 get_address() const { return m_address; } 18511308Santhony.gutierrez@amd.com void set_address(const sc_dt::uint64 address) { m_address = address; } 18611308Santhony.gutierrez@amd.com 18711308Santhony.gutierrez@amd.com // Data related methods. 18811308Santhony.gutierrez@amd.com unsigned char *get_data_ptr() const { return m_data; } 18911308Santhony.gutierrez@amd.com void set_data_ptr(unsigned char *data) { m_data = data; } 19011308Santhony.gutierrez@amd.com 19111308Santhony.gutierrez@amd.com // Transaction length (in bytes) related methods. 19211308Santhony.gutierrez@amd.com unsigned int get_data_length() const { return m_length; } 19311308Santhony.gutierrez@amd.com void set_data_length(const unsigned int length) { m_length = length; } 19411308Santhony.gutierrez@amd.com 19511308Santhony.gutierrez@amd.com // Response status related methods. 19611308Santhony.gutierrez@amd.com bool is_response_ok() const { return (m_response_status > 0); } 19711308Santhony.gutierrez@amd.com bool is_response_error() const { return (m_response_status <= 0); } 19811308Santhony.gutierrez@amd.com tlm_response_status 19911308Santhony.gutierrez@amd.com get_response_status() const 20011308Santhony.gutierrez@amd.com { 20111308Santhony.gutierrez@amd.com return m_response_status; 20211308Santhony.gutierrez@amd.com } 20311308Santhony.gutierrez@amd.com void 20411308Santhony.gutierrez@amd.com set_response_status(const tlm_response_status response_status) 20511308Santhony.gutierrez@amd.com { 20611308Santhony.gutierrez@amd.com m_response_status = response_status; 20711308Santhony.gutierrez@amd.com } 20811308Santhony.gutierrez@amd.com std::string get_response_string() const; 20911308Santhony.gutierrez@amd.com 21011308Santhony.gutierrez@amd.com // Streaming related methods. 21111692Santhony.gutierrez@amd.com unsigned int get_streaming_width() const { return m_streaming_width; } 21211692Santhony.gutierrez@amd.com void 21311308Santhony.gutierrez@amd.com set_streaming_width(const unsigned int streaming_width) 21411308Santhony.gutierrez@amd.com { 21511308Santhony.gutierrez@amd.com m_streaming_width = streaming_width; 21611308Santhony.gutierrez@amd.com } 21711308Santhony.gutierrez@amd.com 21811308Santhony.gutierrez@amd.com // Byte enable related methods. 21911308Santhony.gutierrez@amd.com unsigned char *get_byte_enable_ptr() const { return m_byte_enable; } 22011308Santhony.gutierrez@amd.com void 22111308Santhony.gutierrez@amd.com set_byte_enable_ptr(unsigned char *byte_enable) 22211308Santhony.gutierrez@amd.com { 22311308Santhony.gutierrez@amd.com m_byte_enable = byte_enable; 22411308Santhony.gutierrez@amd.com } 22511308Santhony.gutierrez@amd.com unsigned int 22611308Santhony.gutierrez@amd.com get_byte_enable_length() const 22711308Santhony.gutierrez@amd.com { 22811308Santhony.gutierrez@amd.com return m_byte_enable_length; 22911308Santhony.gutierrez@amd.com } 23011308Santhony.gutierrez@amd.com void 23111308Santhony.gutierrez@amd.com set_byte_enable_length(const unsigned int byte_enable_length) 23211308Santhony.gutierrez@amd.com { 23311308Santhony.gutierrez@amd.com m_byte_enable_length = byte_enable_length; 23411308Santhony.gutierrez@amd.com } 23511308Santhony.gutierrez@amd.com 23611308Santhony.gutierrez@amd.com // This is the "DMI-hint" a slave can set this to true if it 23711308Santhony.gutierrez@amd.com // wants to indicate that a DMI request would be supported: 23811308Santhony.gutierrez@amd.com void 23911308Santhony.gutierrez@amd.com set_dmi_allowed(bool dmi_allowed) 24011308Santhony.gutierrez@amd.com { 24111308Santhony.gutierrez@amd.com m_dmi = dmi_allowed; 24211308Santhony.gutierrez@amd.com } 24311308Santhony.gutierrez@amd.com bool 24411308Santhony.gutierrez@amd.com is_dmi_allowed() const 24511308Santhony.gutierrez@amd.com { 24611308Santhony.gutierrez@amd.com return m_dmi; 24711308Santhony.gutierrez@amd.com } 24811308Santhony.gutierrez@amd.com 24911308Santhony.gutierrez@amd.com // Use full set of attributes in DMI/debug? 25011308Santhony.gutierrez@amd.com tlm_gp_option get_gp_option() const { return m_gp_option; } 25111308Santhony.gutierrez@amd.com void set_gp_option(const tlm_gp_option gp_opt) { m_gp_option = gp_opt; } 25211308Santhony.gutierrez@amd.com 25311308Santhony.gutierrez@amd.com private: 25411308Santhony.gutierrez@amd.com /* --------------------------------------------------------------------- */ 25511308Santhony.gutierrez@amd.com /* Generic Payload attributes: */ 25611308Santhony.gutierrez@amd.com /* --------------------------------------------------------------------- */ 25711308Santhony.gutierrez@amd.com /* - m_command : Type of transaction. Three values supported: */ 25811308Santhony.gutierrez@amd.com /* - TLM_WRITE_COMMAND */ 25911308Santhony.gutierrez@amd.com /* - TLM_READ_COMMAND */ 26011308Santhony.gutierrez@amd.com /* - TLM_IGNORE_COMMAND */ 26111308Santhony.gutierrez@amd.com /* - m_address : Transaction base address (byte-addressing). */ 26211308Santhony.gutierrez@amd.com /* - m_data : When m_command = TLM_WRITE_COMMAND contains a */ 26311308Santhony.gutierrez@amd.com /* pointer to the data to be written in the target.*/ 26411308Santhony.gutierrez@amd.com /* When m_command = TLM_READ_COMMAND contains a */ 26511308Santhony.gutierrez@amd.com /* pointer where to copy the data read from the */ 26611308Santhony.gutierrez@amd.com /* target. */ 26711308Santhony.gutierrez@amd.com /* - m_length : Total number of bytes of the transaction. */ 26811308Santhony.gutierrez@amd.com /* - m_response_status : This attribute indicates whether an error has */ 26911308Santhony.gutierrez@amd.com /* occurred during the transaction. */ 27011308Santhony.gutierrez@amd.com /* Values supported are: */ 27111308Santhony.gutierrez@amd.com /* - TLM_OK_RESP */ 27211308Santhony.gutierrez@amd.com /* - TLM_INCOMPLETE_RESP */ 27311308Santhony.gutierrez@amd.com /* - TLM_GENERIC_ERROR_RESP */ 27411308Santhony.gutierrez@amd.com /* - TLM_ADDRESS_ERROR_RESP */ 27511308Santhony.gutierrez@amd.com /* - TLM_COMMAND_ERROR_RESP */ 27611308Santhony.gutierrez@amd.com /* - TLM_BURST_ERROR_RESP */ 27711308Santhony.gutierrez@amd.com /* - TLM_BYTE_ENABLE_ERROR_RESP */ 27811308Santhony.gutierrez@amd.com /* */ 27911308Santhony.gutierrez@amd.com /* - m_byte_enable : It can be used to create burst transfers where */ 28011308Santhony.gutierrez@amd.com /* the address increment between each beat is greater */ 28111308Santhony.gutierrez@amd.com /* than the word length of each beat, or to place */ 28211308Santhony.gutierrez@amd.com /* words in selected byte lanes of a bus. */ 28311308Santhony.gutierrez@amd.com /* - m_byte_enable_length : For a read or a write command, the target */ 28411308Santhony.gutierrez@amd.com /* interpret the byte enable length attribute as the */ 28511308Santhony.gutierrez@amd.com /* number of elements in the bytes enable array. */ 28611308Santhony.gutierrez@amd.com /* - m_streaming_width : */ 28711308Santhony.gutierrez@amd.com /* --------------------------------------------------------------------- */ 28811308Santhony.gutierrez@amd.com 28911308Santhony.gutierrez@amd.com sc_dt::uint64 m_address; 29011308Santhony.gutierrez@amd.com tlm_command m_command; 29111308Santhony.gutierrez@amd.com unsigned char *m_data; 29211308Santhony.gutierrez@amd.com unsigned int m_length; 29311308Santhony.gutierrez@amd.com tlm_response_status m_response_status; 29411308Santhony.gutierrez@amd.com bool m_dmi; 29511308Santhony.gutierrez@amd.com unsigned char *m_byte_enable; 29611308Santhony.gutierrez@amd.com unsigned int m_byte_enable_length; 29711308Santhony.gutierrez@amd.com unsigned int m_streaming_width; 29811308Santhony.gutierrez@amd.com tlm_gp_option m_gp_option; 29911308Santhony.gutierrez@amd.com 30011308Santhony.gutierrez@amd.com public: 30111308Santhony.gutierrez@amd.com /* --------------------------------------------------------------------- */ 30211308Santhony.gutierrez@amd.com /* Dynamic extension mechanism: */ 30311308Santhony.gutierrez@amd.com /* --------------------------------------------------------------------- */ 30411308Santhony.gutierrez@amd.com /* The extension mechanism is intended to enable initiator modules to */ 30511308Santhony.gutierrez@amd.com /* optionally and transparently add data fields to the */ 30611308Santhony.gutierrez@amd.com /* tlm_generic_payload. Target modules are free to check for extensions */ 30711308Santhony.gutierrez@amd.com /* and may or may not react to the data in the extension fields. The */ 30811308Santhony.gutierrez@amd.com /* definition of the extensions' semantics is solely in the */ 30911308Santhony.gutierrez@amd.com /* responsibility of the user. */ 31011308Santhony.gutierrez@amd.com /* */ 31111308Santhony.gutierrez@amd.com /* The following rules apply: */ 31211308Santhony.gutierrez@amd.com /* */ 31311308Santhony.gutierrez@amd.com /* - Every extension class must be derived from tlm_extension, e.g.: */ 31411308Santhony.gutierrez@amd.com /* class my_extension : public tlm_extension<my_extension> { ... } */ 31511308Santhony.gutierrez@amd.com /* */ 31611308Santhony.gutierrez@amd.com /* - A tlm_generic_payload object should be constructed after C++ */ 31711308Santhony.gutierrez@amd.com /* static initialization time. This way it is guaranteed that the */ 31811308Santhony.gutierrez@amd.com /* extension array is of sufficient size to hold all possible */ 31911308Santhony.gutierrez@amd.com /* extensions. Alternatively, the initiator module can enforce a valid */ 32011308Santhony.gutierrez@amd.com /* extension array size by calling the resize_extensions() method */ 32111308Santhony.gutierrez@amd.com /* once before the first transaction with the payload object is */ 32211308Santhony.gutierrez@amd.com /* initiated. */ 32311308Santhony.gutierrez@amd.com /* */ 32411308Santhony.gutierrez@amd.com /* - Initiators should use the the set_extension(e) or clear_extension(e)*/ 32511308Santhony.gutierrez@amd.com /* methods for manipulating the extension array. The type of the */ 32611308Santhony.gutierrez@amd.com /* argument must be a pointer to the specific registered extension */ 32711308Santhony.gutierrez@amd.com /* type (my_extension in the above example) and is used to */ 32811308Santhony.gutierrez@amd.com /* automatically locate the appropriate index in the array. */ 32911308Santhony.gutierrez@amd.com /* */ 33011308Santhony.gutierrez@amd.com /* - Targets can check for a specific extension by calling */ 33111308Santhony.gutierrez@amd.com /* get_extension(e). e will point to zero if the extension is not */ 33211308Santhony.gutierrez@amd.com /* present. */ 33311308Santhony.gutierrez@amd.com /* */ 334 /* --------------------------------------------------------------------- */ 335 336 // Stick the pointer to an extension into the vector, return the 337 // previous value: 338 template <typename T> 339 T * 340 set_extension(T *ext) 341 { 342 return static_cast<T *>(set_extension(T::ID, ext)); 343 } 344 345 // Non-templatized version with manual index: 346 tlm_extension_base *set_extension( 347 unsigned int index, tlm_extension_base *ext); 348 349 // Stick the pointer to an extension into the vector, return the 350 // previous value and schedule its release. 351 template <typename T> 352 T * 353 set_auto_extension(T *ext) 354 { 355 return static_cast<T *>(set_auto_extension(T::ID, ext)); 356 } 357 358 // Non-templatized version with manual index: 359 tlm_extension_base *set_auto_extension( 360 unsigned int index, tlm_extension_base *ext); 361 362 // Check for an extension, ext will point to 0 if not present. 363 template <typename T> 364 void get_extension(T *& ext) const { ext = get_extension<T>(); } 365 template <typename T> 366 T * 367 get_extension() const 368 { 369 return static_cast<T*>(get_extension(T::ID)); 370 } 371 // Non-templatized version with manual index: 372 tlm_extension_base *get_extension(unsigned int index) const; 373 374 // This call just removes the extension from the txn but does not 375 // call free() or tells the MM to do so it return false if there was 376 // active MM so you are now in an unsafe situation recommended use: 377 // when 100% sure there is no MM. 378 template <typename T> 379 void clear_extension(const T *ext) { clear_extension<T>(); } 380 381 // This call just removes the extension from the txn but does not 382 // call free() or tells the MM to do so it return false if there was 383 // active MM so you are now in an unsafe situation recommended use: when 384 // 100% sure there is no MM. 385 template <typename T> 386 void clear_extension() { clear_extension(T::ID); } 387 388 // This call removes the extension from the txn and does call free() or 389 // tells the MM to do so when the txn is finally done recommended use: 390 // when not sure there is no MM. 391 template <typename T> 392 void release_extension(T *ext) 393 { 394 release_extension<T>(); 395 } 396 397 // This call removes the extension from the txn and does call free() or 398 // tells the MM to do so when the txn is finally done recommended use: 399 // when not sure there is no MM 400 template <typename T> 401 void release_extension() 402 { 403 release_extension(T::ID); 404 } 405 406 private: 407 // Non-templatized version with manual index 408 void clear_extension(unsigned int index); 409 // Non-templatized version with manual index 410 void release_extension(unsigned int index); 411 412 public: 413 // Make sure the extension array is large enough. Can be called once by 414 // an initiator module (before issuing the first transaction) to make 415 // sure that the extension array is of correct size. This is only needed 416 // if the initiator cannot guarantee that the generic payload object is 417 // allocated after C++ static construction time. 418 void resize_extensions(); 419 420 private: 421 tlm_array<tlm_extension_base *> m_extensions; 422 tlm_mm_interface *m_mm; 423 unsigned int m_ref_count; 424}; 425 426} // namespace tlm 427 428#endif /* __SYSTEMC_EXT_TLM_CORE_2_GENERIC_PAYLOAD_GP_HH__ */ 429